blob: cb97b6105f5286fa6c11c8bf787a3e1b49baf52c [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
Dmitry Rozhkov53dd2002018-07-24 14:27:32 +030026#include <linux/async.h>
27#include <linux/delay.h>
28#include <linux/dmi.h>
29#include <linux/jiffies.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070030#include <linux/kernel.h>
Ognjen Galicfa938542018-02-07 15:58:13 +010031#include <linux/list.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/module.h>
Ognjen Galicfa938542018-02-07 15:58:13 +010033#include <linux/mutex.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090034#include <linux/slab.h>
Kyle McMartin25be5822011-03-22 16:19:50 -040035#include <linux/suspend.h>
Dmitry Rozhkov53dd2002018-07-24 14:27:32 +030036#include <linux/types.h>
37
Kamil Iskra4000e6262012-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;
Carlo Caioneec625a32018-04-18 14:04:39 +020078static int battery_check_pmic = 1;
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +040079static unsigned int cache_time = 1000;
80module_param(cache_time, uint, 0644);
81MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +030082
Lan Tianyu3a670cc2014-05-04 11:07:25 +080083#ifdef CONFIG_ACPI_PROCFS_POWER
84extern struct proc_dir_entry *acpi_lock_battery_dir(void);
85extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
Lan Tianyu3a670cc2014-05-04 11:07:25 +080086#endif
87
Alexey Starikovskiyd7380962007-09-26 19:43:04 +040088static const struct acpi_device_id battery_device_ids[] = {
89 {"PNP0C0A", 0},
90 {"", 0},
91};
92
93MODULE_DEVICE_TABLE(acpi, battery_device_ids);
94
Hans de Goededccfae62017-04-19 14:02:10 +020095/* Lists of PMIC ACPI HIDs with an (often better) native battery driver */
96static const char * const acpi_battery_blacklist[] = {
97 "INT33F4", /* X-Powers AXP288 PMIC */
98};
99
Alexey Starikovskiy7b3bcc42009-10-15 14:31:24 +0400100enum {
101 ACPI_BATTERY_ALARM_PRESENT,
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400102 ACPI_BATTERY_XINFO_PRESENT,
Zhang Rui557d5862010-10-22 10:02:06 +0800103 ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
Kamil Iskra4000e6262012-11-16 22:28:58 +0100104 /* On Lenovo Thinkpad models from 2010 and 2011, the power unit
105 switches between mWh and mAh depending on whether the system
106 is running on battery or not. When mAh is the unit, most
107 reported values are incorrect and need to be adjusted by
108 10000/design_voltage. Verified on x201, t410, t410s, and x220.
109 Pre-2010 and 2012 models appear to always report in mWh and
110 are thus unaffected (tested with t42, t61, t500, x200, x300,
111 and x230). Also, in mid-2012 Lenovo issued a BIOS update for
112 the 2011 models that fixes the issue (tested on x220 with a
113 post-1.29 BIOS), but as of Nov. 2012, no such update is
114 available for the 2010 models. */
115 ACPI_BATTERY_QUIRK_THINKPAD_MAH,
Laszlo Totha20136a2018-02-24 10:20:15 +0100116 /* for batteries reporting current capacity with design capacity
117 * on a full charge, but showing degradation in full charge cap.
118 */
119 ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE,
Alexey Starikovskiy7b3bcc42009-10-15 14:31:24 +0400120};
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400121
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400122struct acpi_battery {
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400123 struct mutex lock;
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +0300124 struct mutex sysfs_lock;
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100125 struct power_supply *bat;
126 struct power_supply_desc bat_desc;
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400127 struct acpi_device *device;
Kyle McMartin25be5822011-03-22 16:19:50 -0400128 struct notifier_block pm_nb;
Ognjen Galicfa938542018-02-07 15:58:13 +0100129 struct list_head list;
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400130 unsigned long update_time;
Lan Tianyu016d5ba2013-07-30 14:00:42 +0200131 int revision;
Alexey Starikovskiy7faa1442009-03-27 22:23:52 -0400132 int rate_now;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400133 int capacity_now;
134 int voltage_now;
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400135 int design_capacity;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400136 int full_charge_capacity;
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400137 int technology;
138 int design_voltage;
139 int design_capacity_warning;
140 int design_capacity_low;
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400141 int cycle_count;
142 int measurement_accuracy;
143 int max_sampling_time;
144 int min_sampling_time;
145 int max_averaging_interval;
146 int min_averaging_interval;
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400147 int capacity_granularity_1;
148 int capacity_granularity_2;
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400149 int alarm;
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400150 char model_number[32];
151 char serial_number[32];
152 char type[32];
153 char oem_info[32];
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400154 int state;
155 int power_unit;
Alexey Starikovskiy7b3bcc42009-10-15 14:31:24 +0400156 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157};
158
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100159#define to_acpi_battery(x) power_supply_get_drvdata(x)
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400160
Andy Shevchenkoefd941f2013-03-11 09:17:06 +0000161static inline int acpi_battery_present(struct acpi_battery *battery)
Alexey Starikovskiy78490d82007-05-11 13:18:55 -0400162{
163 return battery->device->status.battery_present;
164}
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400165
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400166static int acpi_battery_technology(struct acpi_battery *battery)
167{
168 if (!strcasecmp("NiCd", battery->type))
169 return POWER_SUPPLY_TECHNOLOGY_NiCd;
170 if (!strcasecmp("NiMH", battery->type))
171 return POWER_SUPPLY_TECHNOLOGY_NiMH;
172 if (!strcasecmp("LION", battery->type))
173 return POWER_SUPPLY_TECHNOLOGY_LION;
Andrey Borzenkovad40e682007-11-10 20:02:49 +0300174 if (!strncasecmp("LI-ION", battery->type, 6))
Alexey Starikovskiy0bde7ee2007-10-28 15:33:10 +0300175 return POWER_SUPPLY_TECHNOLOGY_LION;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400176 if (!strcasecmp("LiP", battery->type))
177 return POWER_SUPPLY_TECHNOLOGY_LIPO;
178 return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
179}
180
Alexey Starikovskiy91044762007-11-13 12:23:06 +0300181static int acpi_battery_get_state(struct acpi_battery *battery);
Alexey Starikovskiyb19073a2007-10-25 17:10:47 -0400182
Richard Hughes56f382a2009-01-25 15:05:50 +0000183static int acpi_battery_is_charged(struct acpi_battery *battery)
184{
Zhang Rui1ac5aaa2014-05-28 15:23:36 +0800185 /* charging, discharging or critical low */
Richard Hughes56f382a2009-01-25 15:05:50 +0000186 if (battery->state != 0)
187 return 0;
188
189 /* battery not reporting charge */
190 if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN ||
191 battery->capacity_now == 0)
192 return 0;
193
194 /* good batteries update full_charge as the batteries degrade */
195 if (battery->full_charge_capacity == battery->capacity_now)
196 return 1;
197
198 /* fallback to using design values for broken batteries */
199 if (battery->design_capacity == battery->capacity_now)
200 return 1;
201
202 /* we don't do any sort of metric based on percentages */
203 return 0;
204}
205
Laszlo Totha20136a2018-02-24 10:20:15 +0100206static bool acpi_battery_is_degraded(struct acpi_battery *battery)
207{
208 return battery->full_charge_capacity && battery->design_capacity &&
209 battery->full_charge_capacity < battery->design_capacity;
210}
211
Hans de Goede19fffc82018-04-12 12:01:59 +0200212static int acpi_battery_handle_discharging(struct acpi_battery *battery)
213{
214 /*
215 * Some devices wrongly report discharging if the battery's charge level
216 * was above the device's start charging threshold atm the AC adapter
217 * was plugged in and the device thus did not start a new charge cycle.
218 */
Hans de Goede1b799c52018-04-12 12:02:00 +0200219 if ((battery_ac_is_broken || power_supply_is_system_supplied()) &&
220 battery->rate_now == 0)
Hans de Goede19fffc82018-04-12 12:01:59 +0200221 return POWER_SUPPLY_STATUS_NOT_CHARGING;
222
223 return POWER_SUPPLY_STATUS_DISCHARGING;
224}
225
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400226static int acpi_battery_get_property(struct power_supply *psy,
227 enum power_supply_property psp,
228 union power_supply_propval *val)
229{
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200230 int ret = 0;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400231 struct acpi_battery *battery = to_acpi_battery(psy);
232
Alexey Starikovskiy91044762007-11-13 12:23:06 +0300233 if (acpi_battery_present(battery)) {
234 /* run battery update only if it is present */
235 acpi_battery_get_state(battery);
236 } else if (psp != POWER_SUPPLY_PROP_PRESENT)
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400237 return -ENODEV;
238 switch (psp) {
239 case POWER_SUPPLY_PROP_STATUS:
Daniel Drake82bf43b2018-03-14 16:42:17 +0800240 if (battery->state & ACPI_BATTERY_STATE_DISCHARGING)
Hans de Goede19fffc82018-04-12 12:01:59 +0200241 val->intval = acpi_battery_handle_discharging(battery);
Daniel Drake82bf43b2018-03-14 16:42:17 +0800242 else if (battery->state & ACPI_BATTERY_STATE_CHARGING)
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400243 val->intval = POWER_SUPPLY_STATUS_CHARGING;
Richard Hughes56f382a2009-01-25 15:05:50 +0000244 else if (acpi_battery_is_charged(battery))
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400245 val->intval = POWER_SUPPLY_STATUS_FULL;
Roland Dreier4c41d3a2007-11-07 15:09:09 -0800246 else
247 val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400248 break;
249 case POWER_SUPPLY_PROP_PRESENT:
250 val->intval = acpi_battery_present(battery);
251 break;
252 case POWER_SUPPLY_PROP_TECHNOLOGY:
253 val->intval = acpi_battery_technology(battery);
254 break;
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400255 case POWER_SUPPLY_PROP_CYCLE_COUNT:
256 val->intval = battery->cycle_count;
257 break;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400258 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200259 if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
260 ret = -ENODEV;
261 else
262 val->intval = battery->design_voltage * 1000;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400263 break;
264 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200265 if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
266 ret = -ENODEV;
267 else
268 val->intval = battery->voltage_now * 1000;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400269 break;
270 case POWER_SUPPLY_PROP_CURRENT_NOW:
Alexey Starikovskiy7faa1442009-03-27 22:23:52 -0400271 case POWER_SUPPLY_PROP_POWER_NOW:
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200272 if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
273 ret = -ENODEV;
274 else
275 val->intval = battery->rate_now * 1000;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400276 break;
277 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
278 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200279 if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
280 ret = -ENODEV;
281 else
282 val->intval = battery->design_capacity * 1000;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400283 break;
284 case POWER_SUPPLY_PROP_CHARGE_FULL:
285 case POWER_SUPPLY_PROP_ENERGY_FULL:
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200286 if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
287 ret = -ENODEV;
288 else
289 val->intval = battery->full_charge_capacity * 1000;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400290 break;
291 case POWER_SUPPLY_PROP_CHARGE_NOW:
292 case POWER_SUPPLY_PROP_ENERGY_NOW:
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200293 if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
294 ret = -ENODEV;
295 else
296 val->intval = battery->capacity_now * 1000;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400297 break;
srinivas pandruvadaa58e1152012-04-05 17:38:54 -0700298 case POWER_SUPPLY_PROP_CAPACITY:
299 if (battery->capacity_now && battery->full_charge_capacity)
300 val->intval = battery->capacity_now * 100/
301 battery->full_charge_capacity;
302 else
303 val->intval = 0;
304 break;
Zhang Rui1ac5aaa2014-05-28 15:23:36 +0800305 case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
306 if (battery->state & ACPI_BATTERY_STATE_CRITICAL)
307 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
308 else if (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) &&
309 (battery->capacity_now <= battery->alarm))
310 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
311 else if (acpi_battery_is_charged(battery))
312 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
313 else
314 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
315 break;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400316 case POWER_SUPPLY_PROP_MODEL_NAME:
317 val->strval = battery->model_number;
318 break;
319 case POWER_SUPPLY_PROP_MANUFACTURER:
320 val->strval = battery->oem_info;
321 break;
maximilian attems7c2670b2008-01-22 18:46:50 +0100322 case POWER_SUPPLY_PROP_SERIAL_NUMBER:
323 val->strval = battery->serial_number;
324 break;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400325 default:
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200326 ret = -EINVAL;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400327 }
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200328 return ret;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400329}
330
331static enum power_supply_property charge_battery_props[] = {
332 POWER_SUPPLY_PROP_STATUS,
333 POWER_SUPPLY_PROP_PRESENT,
334 POWER_SUPPLY_PROP_TECHNOLOGY,
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400335 POWER_SUPPLY_PROP_CYCLE_COUNT,
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400336 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
337 POWER_SUPPLY_PROP_VOLTAGE_NOW,
338 POWER_SUPPLY_PROP_CURRENT_NOW,
339 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
340 POWER_SUPPLY_PROP_CHARGE_FULL,
341 POWER_SUPPLY_PROP_CHARGE_NOW,
srinivas pandruvadaa58e1152012-04-05 17:38:54 -0700342 POWER_SUPPLY_PROP_CAPACITY,
Zhang Rui1ac5aaa2014-05-28 15:23:36 +0800343 POWER_SUPPLY_PROP_CAPACITY_LEVEL,
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400344 POWER_SUPPLY_PROP_MODEL_NAME,
345 POWER_SUPPLY_PROP_MANUFACTURER,
maximilian attems7c2670b2008-01-22 18:46:50 +0100346 POWER_SUPPLY_PROP_SERIAL_NUMBER,
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400347};
348
349static enum power_supply_property energy_battery_props[] = {
350 POWER_SUPPLY_PROP_STATUS,
351 POWER_SUPPLY_PROP_PRESENT,
352 POWER_SUPPLY_PROP_TECHNOLOGY,
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400353 POWER_SUPPLY_PROP_CYCLE_COUNT,
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400354 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
355 POWER_SUPPLY_PROP_VOLTAGE_NOW,
Alexey Starikovskiy7faa1442009-03-27 22:23:52 -0400356 POWER_SUPPLY_PROP_POWER_NOW,
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400357 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
358 POWER_SUPPLY_PROP_ENERGY_FULL,
359 POWER_SUPPLY_PROP_ENERGY_NOW,
srinivas pandruvadaa58e1152012-04-05 17:38:54 -0700360 POWER_SUPPLY_PROP_CAPACITY,
Zhang Rui1ac5aaa2014-05-28 15:23:36 +0800361 POWER_SUPPLY_PROP_CAPACITY_LEVEL,
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400362 POWER_SUPPLY_PROP_MODEL_NAME,
363 POWER_SUPPLY_PROP_MANUFACTURER,
maximilian attems7c2670b2008-01-22 18:46:50 +0100364 POWER_SUPPLY_PROP_SERIAL_NUMBER,
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400365};
366
Hans de Goedeb41901a2018-08-07 09:36:30 +0200367static enum power_supply_property energy_battery_full_cap_broken_props[] = {
368 POWER_SUPPLY_PROP_STATUS,
369 POWER_SUPPLY_PROP_PRESENT,
370 POWER_SUPPLY_PROP_TECHNOLOGY,
371 POWER_SUPPLY_PROP_CYCLE_COUNT,
372 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
373 POWER_SUPPLY_PROP_VOLTAGE_NOW,
374 POWER_SUPPLY_PROP_POWER_NOW,
375 POWER_SUPPLY_PROP_ENERGY_NOW,
376 POWER_SUPPLY_PROP_MODEL_NAME,
377 POWER_SUPPLY_PROP_MANUFACTURER,
378 POWER_SUPPLY_PROP_SERIAL_NUMBER,
379};
380
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381/* --------------------------------------------------------------------------
382 Battery Management
383 -------------------------------------------------------------------------- */
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400384struct acpi_offsets {
385 size_t offset; /* offset inside struct acpi_sbs_battery */
386 u8 mode; /* int or string? */
387};
388
Mathias Krausea4658782015-06-13 14:26:53 +0200389static const struct acpi_offsets state_offsets[] = {
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400390 {offsetof(struct acpi_battery, state), 0},
Alexey Starikovskiy7faa1442009-03-27 22:23:52 -0400391 {offsetof(struct acpi_battery, rate_now), 0},
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400392 {offsetof(struct acpi_battery, capacity_now), 0},
393 {offsetof(struct acpi_battery, voltage_now), 0},
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400394};
395
Mathias Krausea4658782015-06-13 14:26:53 +0200396static const struct acpi_offsets info_offsets[] = {
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400397 {offsetof(struct acpi_battery, power_unit), 0},
398 {offsetof(struct acpi_battery, design_capacity), 0},
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400399 {offsetof(struct acpi_battery, full_charge_capacity), 0},
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400400 {offsetof(struct acpi_battery, technology), 0},
401 {offsetof(struct acpi_battery, design_voltage), 0},
402 {offsetof(struct acpi_battery, design_capacity_warning), 0},
403 {offsetof(struct acpi_battery, design_capacity_low), 0},
404 {offsetof(struct acpi_battery, capacity_granularity_1), 0},
405 {offsetof(struct acpi_battery, capacity_granularity_2), 0},
406 {offsetof(struct acpi_battery, model_number), 1},
407 {offsetof(struct acpi_battery, serial_number), 1},
408 {offsetof(struct acpi_battery, type), 1},
409 {offsetof(struct acpi_battery, oem_info), 1},
410};
411
Mathias Krausea4658782015-06-13 14:26:53 +0200412static const struct acpi_offsets extended_info_offsets[] = {
Lan Tianyu016d5ba2013-07-30 14:00:42 +0200413 {offsetof(struct acpi_battery, revision), 0},
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400414 {offsetof(struct acpi_battery, power_unit), 0},
415 {offsetof(struct acpi_battery, design_capacity), 0},
416 {offsetof(struct acpi_battery, full_charge_capacity), 0},
417 {offsetof(struct acpi_battery, technology), 0},
418 {offsetof(struct acpi_battery, design_voltage), 0},
419 {offsetof(struct acpi_battery, design_capacity_warning), 0},
420 {offsetof(struct acpi_battery, design_capacity_low), 0},
421 {offsetof(struct acpi_battery, cycle_count), 0},
422 {offsetof(struct acpi_battery, measurement_accuracy), 0},
423 {offsetof(struct acpi_battery, max_sampling_time), 0},
424 {offsetof(struct acpi_battery, min_sampling_time), 0},
425 {offsetof(struct acpi_battery, max_averaging_interval), 0},
426 {offsetof(struct acpi_battery, min_averaging_interval), 0},
427 {offsetof(struct acpi_battery, capacity_granularity_1), 0},
428 {offsetof(struct acpi_battery, capacity_granularity_2), 0},
429 {offsetof(struct acpi_battery, model_number), 1},
430 {offsetof(struct acpi_battery, serial_number), 1},
431 {offsetof(struct acpi_battery, type), 1},
432 {offsetof(struct acpi_battery, oem_info), 1},
433};
434
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400435static int extract_package(struct acpi_battery *battery,
436 union acpi_object *package,
Mathias Krausea4658782015-06-13 14:26:53 +0200437 const struct acpi_offsets *offsets, int num)
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300438{
Alexey Starikovskiy106449e2007-10-29 23:29:40 +0300439 int i;
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400440 union acpi_object *element;
441 if (package->type != ACPI_TYPE_PACKAGE)
442 return -EFAULT;
443 for (i = 0; i < num; ++i) {
444 if (package->package.count <= i)
445 return -EFAULT;
446 element = &package->package.elements[i];
447 if (offsets[i].mode) {
Alexey Starikovskiy106449e2007-10-29 23:29:40 +0300448 u8 *ptr = (u8 *)battery + offsets[i].offset;
449 if (element->type == ACPI_TYPE_STRING ||
450 element->type == ACPI_TYPE_BUFFER)
451 strncpy(ptr, element->string.pointer, 32);
452 else if (element->type == ACPI_TYPE_INTEGER) {
453 strncpy(ptr, (u8 *)&element->integer.value,
Lin Ming439913f2010-01-28 10:53:19 +0800454 sizeof(u64));
455 ptr[sizeof(u64)] = 0;
Alexey Starikovskiyb8a1bdb2008-03-17 22:37:42 -0400456 } else
457 *ptr = 0; /* don't have value */
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400458 } else {
Alexey Starikovskiyb8a1bdb2008-03-17 22:37:42 -0400459 int *x = (int *)((u8 *)battery + offsets[i].offset);
460 *x = (element->type == ACPI_TYPE_INTEGER) ?
461 element->integer.value : -1;
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300462 }
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300463 }
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300464 return 0;
465}
466
467static int acpi_battery_get_status(struct acpi_battery *battery)
468{
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400469 if (acpi_bus_get_status(battery->device)) {
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300470 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA"));
471 return -ENODEV;
472 }
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400473 return 0;
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300474}
475
Dave Lambley2d09af42016-11-04 01:05:40 +0000476
477static int extract_battery_info(const int use_bix,
478 struct acpi_battery *battery,
479 const struct acpi_buffer *buffer)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480{
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400481 int result = -EFAULT;
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400482
Dave Lambley2d09af42016-11-04 01:05:40 +0000483 if (use_bix && battery_bix_broken_package)
484 result = extract_package(battery, buffer->pointer,
Lan Tianyua90b4032014-01-06 22:50:37 +0800485 extended_info_offsets + 1,
486 ARRAY_SIZE(extended_info_offsets) - 1);
Dave Lambley2d09af42016-11-04 01:05:40 +0000487 else if (use_bix)
488 result = extract_package(battery, buffer->pointer,
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400489 extended_info_offsets,
490 ARRAY_SIZE(extended_info_offsets));
491 else
Dave Lambley2d09af42016-11-04 01:05:40 +0000492 result = extract_package(battery, buffer->pointer,
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400493 info_offsets, ARRAY_SIZE(info_offsets));
Zhang Rui557d5862010-10-22 10:02:06 +0800494 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
495 battery->full_charge_capacity = battery->design_capacity;
Kamil Iskra4000e6262012-11-16 22:28:58 +0100496 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) &&
497 battery->power_unit && battery->design_voltage) {
498 battery->design_capacity = battery->design_capacity *
499 10000 / battery->design_voltage;
500 battery->full_charge_capacity = battery->full_charge_capacity *
501 10000 / battery->design_voltage;
502 battery->design_capacity_warning =
503 battery->design_capacity_warning *
504 10000 / battery->design_voltage;
505 /* Curiously, design_capacity_low, unlike the rest of them,
506 is correct. */
507 /* capacity_granularity_* equal 1 on the systems tested, so
508 it's impossible to tell if they would need an adjustment
509 or not if their values were higher. */
510 }
Laszlo Totha20136a2018-02-24 10:20:15 +0100511 if (test_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags) &&
512 battery->capacity_now > battery->full_charge_capacity)
513 battery->capacity_now = battery->full_charge_capacity;
514
Patrick Mocheld550d982006-06-27 00:41:40 -0400515 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516}
517
Dave Lambley2d09af42016-11-04 01:05:40 +0000518static int acpi_battery_get_info(struct acpi_battery *battery)
519{
520 const int xinfo = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
521 int use_bix;
522 int result = -ENODEV;
523
524 if (!acpi_battery_present(battery))
525 return 0;
526
527
528 for (use_bix = xinfo ? 1 : 0; use_bix >= 0; use_bix--) {
529 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
530 acpi_status status = AE_ERROR;
531
532 mutex_lock(&battery->lock);
533 status = acpi_evaluate_object(battery->device->handle,
534 use_bix ? "_BIX":"_BIF",
535 NULL, &buffer);
536 mutex_unlock(&battery->lock);
537
538 if (ACPI_FAILURE(status)) {
539 ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s",
540 use_bix ? "_BIX":"_BIF"));
541 } else {
542 result = extract_battery_info(use_bix,
543 battery,
544 &buffer);
545
546 kfree(buffer.pointer);
547 break;
548 }
549 }
550
551 if (!result && !use_bix && xinfo)
552 pr_warn(FW_BUG "The _BIX method is broken, using _BIF.\n");
553
554 return result;
555}
556
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300557static int acpi_battery_get_state(struct acpi_battery *battery)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558{
Len Brown4be44fc2005-08-05 00:44:28 -0400559 int result = 0;
560 acpi_status status = 0;
561 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300563 if (!acpi_battery_present(battery))
564 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700565
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400566 if (battery->update_time &&
567 time_before(jiffies, battery->update_time +
568 msecs_to_jiffies(cache_time)))
569 return 0;
570
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400571 mutex_lock(&battery->lock);
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400572 status = acpi_evaluate_object(battery->device->handle, "_BST",
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400573 NULL, &buffer);
574 mutex_unlock(&battery->lock);
Len Brown5b31d892007-08-15 00:19:26 -0400575
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576 if (ACPI_FAILURE(status)) {
Thomas Renningera6fc6722006-06-26 23:58:43 -0400577 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
Patrick Mocheld550d982006-06-27 00:41:40 -0400578 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 }
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400580
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400581 result = extract_package(battery, buffer.pointer,
582 state_offsets, ARRAY_SIZE(state_offsets));
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400583 battery->update_time = jiffies;
Alexey Starikovskiy78490d82007-05-11 13:18:55 -0400584 kfree(buffer.pointer);
Hector Martinbc76f902009-08-06 15:57:48 -0700585
Lan Tianyu55003b22011-06-30 11:33:12 +0800586 /* For buggy DSDTs that report negative 16-bit values for either
587 * charging or discharging current and/or report 0 as 65536
588 * due to bad math.
589 */
590 if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA &&
591 battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN &&
592 (s16)(battery->rate_now) < 0) {
Hector Martinbc76f902009-08-06 15:57:48 -0700593 battery->rate_now = abs((s16)battery->rate_now);
Dmitry Rozhkovdd1fca92018-07-24 14:27:33 +0300594 pr_warn_once(FW_BUG "battery: (dis)charge rate invalid.\n");
Lan Tianyu55003b22011-06-30 11:33:12 +0800595 }
Hector Martinbc76f902009-08-06 15:57:48 -0700596
Zhang Rui557d5862010-10-22 10:02:06 +0800597 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
598 && battery->capacity_now >= 0 && battery->capacity_now <= 100)
599 battery->capacity_now = (battery->capacity_now *
600 battery->full_charge_capacity) / 100;
Kamil Iskra4000e6262012-11-16 22:28:58 +0100601 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) &&
602 battery->power_unit && battery->design_voltage) {
603 battery->capacity_now = battery->capacity_now *
604 10000 / battery->design_voltage;
605 }
Laszlo Totha20136a2018-02-24 10:20:15 +0100606 if (test_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags) &&
607 battery->capacity_now > battery->full_charge_capacity)
608 battery->capacity_now = battery->full_charge_capacity;
609
Patrick Mocheld550d982006-06-27 00:41:40 -0400610 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611}
612
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400613static int acpi_battery_set_alarm(struct acpi_battery *battery)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614{
Len Brown4be44fc2005-08-05 00:44:28 -0400615 acpi_status status = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400617 if (!acpi_battery_present(battery) ||
Alexey Starikovskiy7b3bcc42009-10-15 14:31:24 +0400618 !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags))
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300619 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400621 mutex_lock(&battery->lock);
Jiang Liu0db98202013-06-29 00:24:39 +0800622 status = acpi_execute_simple_method(battery->device->handle, "_BTP",
623 battery->alarm);
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400624 mutex_unlock(&battery->lock);
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400625
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626 if (ACPI_FAILURE(status))
Patrick Mocheld550d982006-06-27 00:41:40 -0400627 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400629 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", battery->alarm));
Patrick Mocheld550d982006-06-27 00:41:40 -0400630 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631}
632
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300633static int acpi_battery_init_alarm(struct acpi_battery *battery)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634{
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300635 /* See if alarms are supported, and if so, set default */
Jiang Liu952c63e2013-06-29 00:24:38 +0800636 if (!acpi_has_method(battery->device->handle, "_BTP")) {
Alexey Starikovskiy7b3bcc42009-10-15 14:31:24 +0400637 clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400638 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639 }
Alexey Starikovskiy7b3bcc42009-10-15 14:31:24 +0400640 set_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400641 if (!battery->alarm)
642 battery->alarm = battery->design_capacity_warning;
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400643 return acpi_battery_set_alarm(battery);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644}
645
Andrey Borzenkov508df922007-10-28 12:50:09 +0300646static ssize_t acpi_battery_alarm_show(struct device *dev,
647 struct device_attribute *attr,
648 char *buf)
649{
650 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
651 return sprintf(buf, "%d\n", battery->alarm * 1000);
652}
653
654static ssize_t acpi_battery_alarm_store(struct device *dev,
655 struct device_attribute *attr,
656 const char *buf, size_t count)
657{
658 unsigned long x;
659 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
Luis G.F47a08c82014-01-21 15:40:43 +0100660 if (sscanf(buf, "%lu\n", &x) == 1)
Andrey Borzenkov508df922007-10-28 12:50:09 +0300661 battery->alarm = x/1000;
662 if (acpi_battery_present(battery))
663 acpi_battery_set_alarm(battery);
664 return count;
665}
666
Bhumika Goyal82d2b612017-08-21 17:13:07 +0530667static const struct device_attribute alarm_attr = {
Parag Warudkar01e8ef12008-10-18 20:28:50 -0700668 .attr = {.name = "alarm", .mode = 0644},
Andrey Borzenkov508df922007-10-28 12:50:09 +0300669 .show = acpi_battery_alarm_show,
670 .store = acpi_battery_alarm_store,
671};
672
Ognjen Galicfa938542018-02-07 15:58:13 +0100673/*
674 * The Battery Hooking API
675 *
676 * This API is used inside other drivers that need to expose
677 * platform-specific behaviour within the generic driver in a
678 * generic way.
679 *
680 */
681
682static LIST_HEAD(acpi_battery_list);
683static LIST_HEAD(battery_hook_list);
684static DEFINE_MUTEX(hook_mutex);
685
Colin Ian King514bcc52018-02-23 16:32:55 +0000686static void __battery_hook_unregister(struct acpi_battery_hook *hook, int lock)
Ognjen Galicfa938542018-02-07 15:58:13 +0100687{
688 struct acpi_battery *battery;
689 /*
690 * In order to remove a hook, we first need to
691 * de-register all the batteries that are registered.
692 */
693 if (lock)
694 mutex_lock(&hook_mutex);
695 list_for_each_entry(battery, &acpi_battery_list, list) {
696 hook->remove_battery(battery->bat);
697 }
698 list_del(&hook->list);
699 if (lock)
700 mutex_unlock(&hook_mutex);
701 pr_info("extension unregistered: %s\n", hook->name);
702}
703
704void battery_hook_unregister(struct acpi_battery_hook *hook)
705{
706 __battery_hook_unregister(hook, 1);
707}
708EXPORT_SYMBOL_GPL(battery_hook_unregister);
709
710void battery_hook_register(struct acpi_battery_hook *hook)
711{
712 struct acpi_battery *battery;
713
714 mutex_lock(&hook_mutex);
715 INIT_LIST_HEAD(&hook->list);
716 list_add(&hook->list, &battery_hook_list);
717 /*
718 * Now that the driver is registered, we need
719 * to notify the hook that a battery is available
720 * for each battery, so that the driver may add
721 * its attributes.
722 */
723 list_for_each_entry(battery, &acpi_battery_list, list) {
724 if (hook->add_battery(battery->bat)) {
725 /*
726 * If a add-battery returns non-zero,
727 * the registration of the extension has failed,
728 * and we will not add it to the list of loaded
729 * hooks.
730 */
731 pr_err("extension failed to load: %s", hook->name);
732 __battery_hook_unregister(hook, 0);
Jouke Witteveen673b4272018-07-04 12:27:15 +0200733 goto end;
Ognjen Galicfa938542018-02-07 15:58:13 +0100734 }
735 }
736 pr_info("new extension: %s\n", hook->name);
Jouke Witteveen673b4272018-07-04 12:27:15 +0200737end:
Ognjen Galicfa938542018-02-07 15:58:13 +0100738 mutex_unlock(&hook_mutex);
739}
740EXPORT_SYMBOL_GPL(battery_hook_register);
741
742/*
743 * This function gets called right after the battery sysfs
744 * attributes have been added, so that the drivers that
745 * define custom sysfs attributes can add their own.
Rafael J. Wysocki7a4ea102018-03-13 10:07:49 +0100746*/
Ognjen Galicfa938542018-02-07 15:58:13 +0100747static void battery_hook_add_battery(struct acpi_battery *battery)
748{
Jouke Witteveen673b4272018-07-04 12:27:15 +0200749 struct acpi_battery_hook *hook_node, *tmp;
Ognjen Galicfa938542018-02-07 15:58:13 +0100750
751 mutex_lock(&hook_mutex);
752 INIT_LIST_HEAD(&battery->list);
753 list_add(&battery->list, &acpi_battery_list);
754 /*
755 * Since we added a new battery to the list, we need to
756 * iterate over the hooks and call add_battery for each
757 * hook that was registered. This usually happens
758 * when a battery gets hotplugged or initialized
759 * during the battery module initialization.
760 */
Jouke Witteveen673b4272018-07-04 12:27:15 +0200761 list_for_each_entry_safe(hook_node, tmp, &battery_hook_list, list) {
Ognjen Galicfa938542018-02-07 15:58:13 +0100762 if (hook_node->add_battery(battery->bat)) {
763 /*
764 * The notification of the extensions has failed, to
765 * prevent further errors we will unload the extension.
766 */
Ognjen Galicfa938542018-02-07 15:58:13 +0100767 pr_err("error in extension, unloading: %s",
768 hook_node->name);
Jouke Witteveen673b4272018-07-04 12:27:15 +0200769 __battery_hook_unregister(hook_node, 0);
Ognjen Galicfa938542018-02-07 15:58:13 +0100770 }
771 }
772 mutex_unlock(&hook_mutex);
773}
774
775static void battery_hook_remove_battery(struct acpi_battery *battery)
776{
777 struct acpi_battery_hook *hook;
778
779 mutex_lock(&hook_mutex);
780 /*
781 * Before removing the hook, we need to remove all
782 * custom attributes from the battery.
783 */
784 list_for_each_entry(hook, &battery_hook_list, list) {
785 hook->remove_battery(battery->bat);
786 }
787 /* Then, just remove the battery from the list */
788 list_del(&battery->list);
789 mutex_unlock(&hook_mutex);
790}
791
792static void __exit battery_hook_exit(void)
793{
794 struct acpi_battery_hook *hook;
795 struct acpi_battery_hook *ptr;
796 /*
797 * At this point, the acpi_bus_unregister_driver()
798 * has called remove for all batteries. We just
799 * need to remove the hooks.
800 */
801 list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) {
802 __battery_hook_unregister(hook, 1);
803 }
804 mutex_destroy(&hook_mutex);
805}
806
Andrey Borzenkov508df922007-10-28 12:50:09 +0300807static int sysfs_add_battery(struct acpi_battery *battery)
808{
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100809 struct power_supply_config psy_cfg = { .drv_data = battery, };
Andrey Borzenkov508df922007-10-28 12:50:09 +0300810
Lan Tianyuae6f6182011-06-30 11:32:40 +0800811 if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) {
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100812 battery->bat_desc.properties = charge_battery_props;
813 battery->bat_desc.num_properties =
Andrey Borzenkov508df922007-10-28 12:50:09 +0300814 ARRAY_SIZE(charge_battery_props);
Hans de Goedeb41901a2018-08-07 09:36:30 +0200815 } else if (battery->full_charge_capacity == 0) {
816 battery->bat_desc.properties =
817 energy_battery_full_cap_broken_props;
818 battery->bat_desc.num_properties =
819 ARRAY_SIZE(energy_battery_full_cap_broken_props);
Andrey Borzenkov508df922007-10-28 12:50:09 +0300820 } else {
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100821 battery->bat_desc.properties = energy_battery_props;
822 battery->bat_desc.num_properties =
Andrey Borzenkov508df922007-10-28 12:50:09 +0300823 ARRAY_SIZE(energy_battery_props);
824 }
825
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100826 battery->bat_desc.name = acpi_device_bid(battery->device);
827 battery->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY;
828 battery->bat_desc.get_property = acpi_battery_get_property;
Andrey Borzenkov508df922007-10-28 12:50:09 +0300829
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100830 battery->bat = power_supply_register_no_ws(&battery->device->dev,
831 &battery->bat_desc, &psy_cfg);
Zhang Ruie0d1f092014-05-28 15:23:38 +0800832
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100833 if (IS_ERR(battery->bat)) {
834 int result = PTR_ERR(battery->bat);
835
836 battery->bat = NULL;
Andrey Borzenkov508df922007-10-28 12:50:09 +0300837 return result;
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100838 }
Ognjen Galicfa938542018-02-07 15:58:13 +0100839 battery_hook_add_battery(battery);
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100840 return device_create_file(&battery->bat->dev, &alarm_attr);
Andrey Borzenkov508df922007-10-28 12:50:09 +0300841}
842
843static void sysfs_remove_battery(struct acpi_battery *battery)
844{
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +0300845 mutex_lock(&battery->sysfs_lock);
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100846 if (!battery->bat) {
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +0300847 mutex_unlock(&battery->sysfs_lock);
Andrey Borzenkov508df922007-10-28 12:50:09 +0300848 return;
Lan Tianyu9c921c222011-06-30 11:34:12 +0800849 }
Ognjen Galicfa938542018-02-07 15:58:13 +0100850 battery_hook_remove_battery(battery);
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100851 device_remove_file(&battery->bat->dev, &alarm_attr);
852 power_supply_unregister(battery->bat);
853 battery->bat = NULL;
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +0300854 mutex_unlock(&battery->sysfs_lock);
Hector Martinbc76f902009-08-06 15:57:48 -0700855}
856
Kamil Iskra4000e6262012-11-16 22:28:58 +0100857static void find_battery(const struct dmi_header *dm, void *private)
858{
859 struct acpi_battery *battery = (struct acpi_battery *)private;
860 /* Note: the hardcoded offsets below have been extracted from
861 the source code of dmidecode. */
862 if (dm->type == DMI_ENTRY_PORTABLE_BATTERY && dm->length >= 8) {
863 const u8 *dmi_data = (const u8 *)(dm + 1);
864 int dmi_capacity = get_unaligned((const u16 *)(dmi_data + 6));
865 if (dm->length >= 18)
866 dmi_capacity *= dmi_data[17];
867 if (battery->design_capacity * battery->design_voltage / 1000
868 != dmi_capacity &&
869 battery->design_capacity * 10 == dmi_capacity)
870 set_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH,
871 &battery->flags);
872 }
873}
874
Zhang Rui557d5862010-10-22 10:02:06 +0800875/*
876 * According to the ACPI spec, some kinds of primary batteries can
877 * report percentage battery remaining capacity directly to OS.
878 * In this case, it reports the Last Full Charged Capacity == 100
879 * and BatteryPresentRate == 0xFFFFFFFF.
880 *
881 * Now we found some battery reports percentage remaining capacity
882 * even if it's rechargeable.
883 * https://bugzilla.kernel.org/show_bug.cgi?id=15979
884 *
885 * Handle this correctly so that they won't break userspace.
886 */
Lan Tianyu7b786222011-06-30 11:33:27 +0800887static void acpi_battery_quirks(struct acpi_battery *battery)
Zhang Rui557d5862010-10-22 10:02:06 +0800888{
889 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
Nicholas Mazzuca0f4c6542013-05-08 23:11:15 +0000890 return;
Zhang Rui557d5862010-10-22 10:02:06 +0800891
Nicholas Mazzuca0f4c6542013-05-08 23:11:15 +0000892 if (battery->full_charge_capacity == 100 &&
893 battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
894 battery->capacity_now >= 0 && battery->capacity_now <= 100) {
Zhang Rui557d5862010-10-22 10:02:06 +0800895 set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags);
896 battery->full_charge_capacity = battery->design_capacity;
897 battery->capacity_now = (battery->capacity_now *
898 battery->full_charge_capacity) / 100;
899 }
Kamil Iskra4000e6262012-11-16 22:28:58 +0100900
901 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags))
Nicholas Mazzuca0f4c6542013-05-08 23:11:15 +0000902 return;
Kamil Iskra4000e6262012-11-16 22:28:58 +0100903
904 if (battery->power_unit && dmi_name_in_vendors("LENOVO")) {
905 const char *s;
906 s = dmi_get_system_info(DMI_PRODUCT_VERSION);
Rasmus Villemoesffd8a732014-09-16 22:51:24 +0200907 if (s && !strncasecmp(s, "ThinkPad", 8)) {
Kamil Iskra4000e6262012-11-16 22:28:58 +0100908 dmi_walk(find_battery, battery);
909 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH,
910 &battery->flags) &&
911 battery->design_voltage) {
912 battery->design_capacity =
913 battery->design_capacity *
914 10000 / battery->design_voltage;
915 battery->full_charge_capacity =
916 battery->full_charge_capacity *
917 10000 / battery->design_voltage;
918 battery->design_capacity_warning =
919 battery->design_capacity_warning *
920 10000 / battery->design_voltage;
921 battery->capacity_now = battery->capacity_now *
922 10000 / battery->design_voltage;
923 }
924 }
925 }
Laszlo Totha20136a2018-02-24 10:20:15 +0100926
927 if (test_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags))
928 return;
929
930 if (acpi_battery_is_degraded(battery) &&
931 battery->capacity_now > battery->full_charge_capacity) {
932 set_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags);
933 battery->capacity_now = battery->full_charge_capacity;
934 }
Zhang Rui557d5862010-10-22 10:02:06 +0800935}
936
Lan Tianyu9e50bc12014-05-04 14:07:06 +0800937static int acpi_battery_update(struct acpi_battery *battery, bool resume)
Vladimir Lebedev4bd35cd2007-02-10 01:43:48 -0500938{
Lucas Rangit Magasweran82f2d302018-07-14 15:40:18 -0700939 int result = acpi_battery_get_status(battery);
940
Andrey Borzenkov508df922007-10-28 12:50:09 +0300941 if (result)
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300942 return result;
Lucas Rangit Magasweran82f2d302018-07-14 15:40:18 -0700943
Andrey Borzenkov508df922007-10-28 12:50:09 +0300944 if (!acpi_battery_present(battery)) {
945 sysfs_remove_battery(battery);
Alexey Starikovskiy97749cd2008-01-01 14:27:24 -0500946 battery->update_time = 0;
Andrey Borzenkov508df922007-10-28 12:50:09 +0300947 return 0;
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300948 }
Lan Tianyu9e50bc12014-05-04 14:07:06 +0800949
950 if (resume)
951 return 0;
952
Lucas Rangit Magasweran82f2d302018-07-14 15:40:18 -0700953 if (!battery->update_time) {
Alexey Starikovskiy97749cd2008-01-01 14:27:24 -0500954 result = acpi_battery_get_info(battery);
955 if (result)
956 return result;
957 acpi_battery_init_alarm(battery);
958 }
Carlos Garnacho12c78ca2016-08-10 17:24:15 +0200959
960 result = acpi_battery_get_state(battery);
961 if (result)
962 return result;
963 acpi_battery_quirks(battery);
964
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100965 if (!battery->bat) {
Stefan Hajnoczieb03cb02011-07-12 09:03:29 +0100966 result = sysfs_add_battery(battery);
967 if (result)
968 return result;
969 }
Zhang Ruie0d1f092014-05-28 15:23:38 +0800970
971 /*
972 * Wakeup the system if battery is critical low
973 * or lower than the alarm level
974 */
975 if ((battery->state & ACPI_BATTERY_STATE_CRITICAL) ||
976 (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) &&
977 (battery->capacity_now <= battery->alarm)))
Rafael J. Wysocki33e4f802017-06-12 22:56:34 +0200978 acpi_pm_wakeup_event(&battery->device->dev);
Zhang Ruie0d1f092014-05-28 15:23:38 +0800979
Zhang Rui557d5862010-10-22 10:02:06 +0800980 return result;
Vladimir Lebedev4bd35cd2007-02-10 01:43:48 -0500981}
982
Rafael J. Wysockida8aeb92011-01-06 23:42:27 +0100983static void acpi_battery_refresh(struct acpi_battery *battery)
984{
Andy Whitcroftc5971452012-05-03 14:48:26 +0100985 int power_unit;
986
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100987 if (!battery->bat)
Rafael J. Wysockida8aeb92011-01-06 23:42:27 +0100988 return;
989
Andy Whitcroftc5971452012-05-03 14:48:26 +0100990 power_unit = battery->power_unit;
991
Rafael J. Wysockida8aeb92011-01-06 23:42:27 +0100992 acpi_battery_get_info(battery);
Andy Whitcroftc5971452012-05-03 14:48:26 +0100993
994 if (power_unit == battery->power_unit)
995 return;
996
997 /* The battery has changed its reporting units. */
Rafael J. Wysockida8aeb92011-01-06 23:42:27 +0100998 sysfs_remove_battery(battery);
999 sysfs_add_battery(battery);
1000}
1001
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002/* --------------------------------------------------------------------------
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001003 FS Interface (/proc)
1004 -------------------------------------------------------------------------- */
1005
1006#ifdef CONFIG_ACPI_PROCFS_POWER
1007static struct proc_dir_entry *acpi_battery_dir;
1008
Mathias Krause27059b92015-06-13 14:26:54 +02001009static const char *acpi_battery_units(const struct acpi_battery *battery)
1010{
1011 return (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) ?
1012 "mA" : "mW";
1013}
1014
Christoph Hellwige7b087f2018-04-11 16:27:14 +02001015static int acpi_battery_info_proc_show(struct seq_file *seq, void *offset)
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001016{
1017 struct acpi_battery *battery = seq->private;
Christoph Hellwige7b087f2018-04-11 16:27:14 +02001018 int result = acpi_battery_update(battery, false);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001019
1020 if (result)
1021 goto end;
1022
1023 seq_printf(seq, "present: %s\n",
1024 acpi_battery_present(battery) ? "yes" : "no");
1025 if (!acpi_battery_present(battery))
1026 goto end;
1027 if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
1028 seq_printf(seq, "design capacity: unknown\n");
1029 else
1030 seq_printf(seq, "design capacity: %d %sh\n",
1031 battery->design_capacity,
1032 acpi_battery_units(battery));
1033
1034 if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
1035 seq_printf(seq, "last full capacity: unknown\n");
1036 else
1037 seq_printf(seq, "last full capacity: %d %sh\n",
1038 battery->full_charge_capacity,
1039 acpi_battery_units(battery));
1040
1041 seq_printf(seq, "battery technology: %srechargeable\n",
Dmitry Rozhkov27544352018-07-24 14:27:34 +03001042 battery->technology ? "" : "non-");
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001043
1044 if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
1045 seq_printf(seq, "design voltage: unknown\n");
1046 else
1047 seq_printf(seq, "design voltage: %d mV\n",
1048 battery->design_voltage);
1049 seq_printf(seq, "design capacity warning: %d %sh\n",
1050 battery->design_capacity_warning,
1051 acpi_battery_units(battery));
1052 seq_printf(seq, "design capacity low: %d %sh\n",
1053 battery->design_capacity_low,
1054 acpi_battery_units(battery));
1055 seq_printf(seq, "cycle count: %i\n", battery->cycle_count);
1056 seq_printf(seq, "capacity granularity 1: %d %sh\n",
1057 battery->capacity_granularity_1,
1058 acpi_battery_units(battery));
1059 seq_printf(seq, "capacity granularity 2: %d %sh\n",
1060 battery->capacity_granularity_2,
1061 acpi_battery_units(battery));
1062 seq_printf(seq, "model number: %s\n", battery->model_number);
1063 seq_printf(seq, "serial number: %s\n", battery->serial_number);
1064 seq_printf(seq, "battery type: %s\n", battery->type);
1065 seq_printf(seq, "OEM info: %s\n", battery->oem_info);
1066 end:
1067 if (result)
1068 seq_printf(seq, "ERROR: Unable to read battery info\n");
1069 return result;
1070}
1071
Christoph Hellwige7b087f2018-04-11 16:27:14 +02001072static int acpi_battery_state_proc_show(struct seq_file *seq, void *offset)
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001073{
1074 struct acpi_battery *battery = seq->private;
Christoph Hellwige7b087f2018-04-11 16:27:14 +02001075 int result = acpi_battery_update(battery, false);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001076
1077 if (result)
1078 goto end;
1079
1080 seq_printf(seq, "present: %s\n",
1081 acpi_battery_present(battery) ? "yes" : "no");
1082 if (!acpi_battery_present(battery))
1083 goto end;
1084
1085 seq_printf(seq, "capacity state: %s\n",
1086 (battery->state & 0x04) ? "critical" : "ok");
1087 if ((battery->state & 0x01) && (battery->state & 0x02))
1088 seq_printf(seq,
1089 "charging state: charging/discharging\n");
1090 else if (battery->state & 0x01)
1091 seq_printf(seq, "charging state: discharging\n");
1092 else if (battery->state & 0x02)
1093 seq_printf(seq, "charging state: charging\n");
1094 else
1095 seq_printf(seq, "charging state: charged\n");
1096
1097 if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
1098 seq_printf(seq, "present rate: unknown\n");
1099 else
1100 seq_printf(seq, "present rate: %d %s\n",
1101 battery->rate_now, acpi_battery_units(battery));
1102
1103 if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
1104 seq_printf(seq, "remaining capacity: unknown\n");
1105 else
1106 seq_printf(seq, "remaining capacity: %d %sh\n",
1107 battery->capacity_now, acpi_battery_units(battery));
1108 if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
1109 seq_printf(seq, "present voltage: unknown\n");
1110 else
1111 seq_printf(seq, "present voltage: %d mV\n",
1112 battery->voltage_now);
1113 end:
1114 if (result)
1115 seq_printf(seq, "ERROR: Unable to read battery state\n");
1116
1117 return result;
1118}
1119
Christoph Hellwige7b087f2018-04-11 16:27:14 +02001120static int acpi_battery_alarm_proc_show(struct seq_file *seq, void *offset)
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001121{
1122 struct acpi_battery *battery = seq->private;
Christoph Hellwige7b087f2018-04-11 16:27:14 +02001123 int result = acpi_battery_update(battery, false);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001124
1125 if (result)
1126 goto end;
1127
1128 if (!acpi_battery_present(battery)) {
1129 seq_printf(seq, "present: no\n");
1130 goto end;
1131 }
1132 seq_printf(seq, "alarm: ");
Dmitry Rozhkov27544352018-07-24 14:27:34 +03001133 if (battery->alarm) {
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001134 seq_printf(seq, "%u %sh\n", battery->alarm,
1135 acpi_battery_units(battery));
Dmitry Rozhkov27544352018-07-24 14:27:34 +03001136 } else {
1137 seq_printf(seq, "unsupported\n");
1138 }
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001139 end:
1140 if (result)
1141 seq_printf(seq, "ERROR: Unable to read battery alarm\n");
1142 return result;
1143}
1144
1145static ssize_t acpi_battery_write_alarm(struct file *file,
1146 const char __user * buffer,
1147 size_t count, loff_t * ppos)
1148{
1149 int result = 0;
1150 char alarm_string[12] = { '\0' };
1151 struct seq_file *m = file->private_data;
1152 struct acpi_battery *battery = m->private;
1153
1154 if (!battery || (count > sizeof(alarm_string) - 1))
1155 return -EINVAL;
1156 if (!acpi_battery_present(battery)) {
1157 result = -ENODEV;
1158 goto end;
1159 }
1160 if (copy_from_user(alarm_string, buffer, count)) {
1161 result = -EFAULT;
1162 goto end;
1163 }
1164 alarm_string[count] = '\0';
Christoph Jaeger3d915892014-06-13 21:49:58 +02001165 if (kstrtoint(alarm_string, 0, &battery->alarm)) {
1166 result = -EINVAL;
1167 goto end;
1168 }
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001169 result = acpi_battery_set_alarm(battery);
1170 end:
Dmitry Rozhkov27544352018-07-24 14:27:34 +03001171 if (result)
1172 return result;
1173 return count;
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001174}
1175
Christoph Hellwige7b087f2018-04-11 16:27:14 +02001176static int acpi_battery_alarm_proc_open(struct inode *inode, struct file *file)
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001177{
Christoph Hellwige7b087f2018-04-11 16:27:14 +02001178 return single_open(file, acpi_battery_alarm_proc_show, PDE_DATA(inode));
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001179}
1180
Christoph Hellwige7b087f2018-04-11 16:27:14 +02001181static const struct file_operations acpi_battery_alarm_fops = {
1182 .owner = THIS_MODULE,
1183 .open = acpi_battery_alarm_proc_open,
1184 .read = seq_read,
1185 .write = acpi_battery_write_alarm,
1186 .llseek = seq_lseek,
1187 .release = single_release,
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001188};
1189
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001190static int acpi_battery_add_fs(struct acpi_device *device)
1191{
Dmitry Rozhkovdd1fca92018-07-24 14:27:33 +03001192 pr_warning(PREFIX "Deprecated procfs I/F for battery is loaded, please retry with CONFIG_ACPI_PROCFS_POWER cleared\n");
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001193 if (!acpi_device_dir(device)) {
1194 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
1195 acpi_battery_dir);
1196 if (!acpi_device_dir(device))
1197 return -ENODEV;
1198 }
1199
Christoph Hellwige7b087f2018-04-11 16:27:14 +02001200 if (!proc_create_single_data("info", S_IRUGO, acpi_device_dir(device),
1201 acpi_battery_info_proc_show, acpi_driver_data(device)))
1202 return -ENODEV;
1203 if (!proc_create_single_data("state", S_IRUGO, acpi_device_dir(device),
1204 acpi_battery_state_proc_show, acpi_driver_data(device)))
1205 return -ENODEV;
1206 if (!proc_create_data("alarm", S_IFREG | S_IRUGO | S_IWUSR,
1207 acpi_device_dir(device), &acpi_battery_alarm_fops,
1208 acpi_driver_data(device)))
1209 return -ENODEV;
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001210 return 0;
1211}
1212
1213static void acpi_battery_remove_fs(struct acpi_device *device)
1214{
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001215 if (!acpi_device_dir(device))
1216 return;
Christoph Hellwige7b087f2018-04-11 16:27:14 +02001217 remove_proc_subtree(acpi_device_bid(device), acpi_battery_dir);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001218 acpi_device_dir(device) = NULL;
1219}
1220
1221#endif
1222
1223/* --------------------------------------------------------------------------
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224 Driver Interface
1225 -------------------------------------------------------------------------- */
1226
Bjorn Helgaasd9406692009-04-30 09:35:47 -06001227static void acpi_battery_notify(struct acpi_device *device, u32 event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228{
Bjorn Helgaasd9406692009-04-30 09:35:47 -06001229 struct acpi_battery *battery = acpi_driver_data(device);
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +01001230 struct power_supply *old;
Bjorn Helgaasd9406692009-04-30 09:35:47 -06001231
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232 if (!battery)
Patrick Mocheld550d982006-06-27 00:41:40 -04001233 return;
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +01001234 old = battery->bat;
Alexander Mezinf43691c2014-06-04 02:01:23 +07001235 /*
1236 * On Acer Aspire V5-573G notifications are sometimes triggered too
1237 * early. For example, when AC is unplugged and notification is
1238 * triggered, battery state is still reported as "Full", and changes to
1239 * "Discharging" only after short delay, without any notification.
1240 */
1241 if (battery_notification_delay_ms > 0)
1242 msleep(battery_notification_delay_ms);
Rafael J. Wysockida8aeb92011-01-06 23:42:27 +01001243 if (event == ACPI_BATTERY_NOTIFY_INFO)
1244 acpi_battery_refresh(battery);
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001245 acpi_battery_update(battery, false);
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +04001246 acpi_bus_generate_netlink_event(device->pnp.device_class,
Kay Sievers07944692008-10-30 01:18:59 +01001247 dev_name(&device->dev), event,
Vladimir Lebedev9ea7d572007-02-20 15:48:06 +03001248 acpi_battery_present(battery));
Alexander Mezin411e0f72014-03-12 00:58:47 +07001249 acpi_notifier_call_chain(device, event, acpi_battery_present(battery));
Justin P. Mattock2345baf2009-12-13 14:42:36 -08001250 /* acpi_battery_update could remove power_supply object */
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +01001251 if (old && battery->bat)
1252 power_supply_changed(battery->bat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253}
1254
Kyle McMartin25be5822011-03-22 16:19:50 -04001255static int battery_notify(struct notifier_block *nb,
1256 unsigned long mode, void *_unused)
1257{
1258 struct acpi_battery *battery = container_of(nb, struct acpi_battery,
1259 pm_nb);
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001260 int result;
1261
Kyle McMartin25be5822011-03-22 16:19:50 -04001262 switch (mode) {
Lan Tianyud5a59112011-06-30 11:33:40 +08001263 case PM_POST_HIBERNATION:
Kyle McMartin25be5822011-03-22 16:19:50 -04001264 case PM_POST_SUSPEND:
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001265 if (!acpi_battery_present(battery))
1266 return 0;
1267
Dmitry Rozhkov27544352018-07-24 14:27:34 +03001268 if (battery->bat) {
1269 acpi_battery_refresh(battery);
1270 } else {
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001271 result = acpi_battery_get_info(battery);
1272 if (result)
1273 return result;
1274
1275 result = sysfs_add_battery(battery);
1276 if (result)
1277 return result;
Dmitry Rozhkov27544352018-07-24 14:27:34 +03001278 }
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001279
1280 acpi_battery_init_alarm(battery);
1281 acpi_battery_get_state(battery);
Kyle McMartin25be5822011-03-22 16:19:50 -04001282 break;
1283 }
1284
1285 return 0;
1286}
1287
Mathias Krause048d16d2015-06-13 14:26:55 +02001288static int __init
1289battery_bix_broken_package_quirk(const struct dmi_system_id *d)
Alexander Mezin3f5dc082014-06-04 02:01:22 +07001290{
1291 battery_bix_broken_package = 1;
1292 return 0;
1293}
1294
Mathias Krause048d16d2015-06-13 14:26:55 +02001295static int __init
1296battery_notification_delay_quirk(const struct dmi_system_id *d)
Alexander Mezinf43691c2014-06-04 02:01:23 +07001297{
1298 battery_notification_delay_ms = 1000;
1299 return 0;
1300}
1301
Hans de Goede1b799c52018-04-12 12:02:00 +02001302static int __init
1303battery_ac_is_broken_quirk(const struct dmi_system_id *d)
1304{
1305 battery_ac_is_broken = 1;
1306 return 0;
1307}
1308
Carlo Caioneec625a32018-04-18 14:04:39 +02001309static int __init
1310battery_do_not_check_pmic_quirk(const struct dmi_system_id *d)
1311{
1312 battery_check_pmic = 0;
1313 return 0;
1314}
1315
Mathias Krause048d16d2015-06-13 14:26:55 +02001316static const struct dmi_system_id bat_dmi_table[] __initconst = {
Lan Tianyua90b4032014-01-06 22:50:37 +08001317 {
Hans de Goede91afa072018-04-12 12:01:58 +02001318 /* NEC LZ750/LS */
Alexander Mezin3f5dc082014-06-04 02:01:22 +07001319 .callback = battery_bix_broken_package_quirk,
Lan Tianyua90b4032014-01-06 22:50:37 +08001320 .matches = {
1321 DMI_MATCH(DMI_SYS_VENDOR, "NEC"),
1322 DMI_MATCH(DMI_PRODUCT_NAME, "PC-LZ750LS"),
1323 },
1324 },
Alexander Mezinf43691c2014-06-04 02:01:23 +07001325 {
Hans de Goede91afa072018-04-12 12:01:58 +02001326 /* Acer Aspire V5-573G */
Alexander Mezinf43691c2014-06-04 02:01:23 +07001327 .callback = battery_notification_delay_quirk,
Alexander Mezinf43691c2014-06-04 02:01:23 +07001328 .matches = {
1329 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
1330 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-573G"),
1331 },
1332 },
Hans de Goede1b799c52018-04-12 12:02:00 +02001333 {
1334 /* Point of View mobii wintab p800w */
1335 .callback = battery_ac_is_broken_quirk,
1336 .matches = {
1337 DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
1338 DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
1339 DMI_MATCH(DMI_BIOS_VERSION, "3BAIR1013"),
1340 /* Above matches are too generic, add bios-date match */
1341 DMI_MATCH(DMI_BIOS_DATE, "08/22/2014"),
1342 },
1343 },
Carlo Caioneec625a32018-04-18 14:04:39 +02001344 {
1345 /* ECS EF20EA */
1346 .callback = battery_do_not_check_pmic_quirk,
1347 .matches = {
1348 DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"),
1349 },
1350 },
1351 {
1352 /* Lenovo Ideapad Miix 320 */
1353 .callback = battery_do_not_check_pmic_quirk,
1354 .matches = {
1355 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
1356 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80XF"),
1357 DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
1358 },
1359 },
Lan Tianyua90b4032014-01-06 22:50:37 +08001360 {},
1361};
1362
Lan Tianyu75646e72014-07-07 15:47:12 +08001363/*
1364 * Some machines'(E,G Lenovo Z480) ECs are not stable
1365 * during boot up and this causes battery driver fails to be
1366 * probed due to failure of getting battery information
1367 * from EC sometimes. After several retries, the operation
1368 * may work. So add retry code here and 20ms sleep between
1369 * every retries.
1370 */
1371static int acpi_battery_update_retry(struct acpi_battery *battery)
1372{
1373 int retry, ret;
1374
1375 for (retry = 5; retry; retry--) {
1376 ret = acpi_battery_update(battery, false);
1377 if (!ret)
1378 break;
1379
1380 msleep(20);
1381 }
1382 return ret;
1383}
1384
Len Brown4be44fc2005-08-05 00:44:28 -04001385static int acpi_battery_add(struct acpi_device *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386{
Len Brown4be44fc2005-08-05 00:44:28 -04001387 int result = 0;
Len Brown4be44fc2005-08-05 00:44:28 -04001388 struct acpi_battery *battery = NULL;
Jiang Liu952c63e2013-06-29 00:24:38 +08001389
Linus Torvalds1da177e2005-04-16 15:20:36 -07001390 if (!device)
Patrick Mocheld550d982006-06-27 00:41:40 -04001391 return -EINVAL;
Lan Tianyu40e7fcb2014-11-23 21:22:54 +08001392
1393 if (device->dep_unmet)
1394 return -EPROBE_DEFER;
1395
Burman Yan36bcbec2006-12-19 12:56:11 -08001396 battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397 if (!battery)
Patrick Mocheld550d982006-06-27 00:41:40 -04001398 return -ENOMEM;
Patrick Mochel145def82006-05-19 16:54:39 -04001399 battery->device = device;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001400 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
1401 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
Pavel Machekdb89b4f2008-09-22 14:37:34 -07001402 device->driver_data = battery;
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +04001403 mutex_init(&battery->lock);
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +03001404 mutex_init(&battery->sysfs_lock);
Jiang Liu952c63e2013-06-29 00:24:38 +08001405 if (acpi_has_method(battery->device->handle, "_BIX"))
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +04001406 set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
Lan Tianyu75646e72014-07-07 15:47:12 +08001407
1408 result = acpi_battery_update_retry(battery);
Stefan Hajnoczieb03cb02011-07-12 09:03:29 +01001409 if (result)
1410 goto fail;
Lan Tianyu75646e72014-07-07 15:47:12 +08001411
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001412#ifdef CONFIG_ACPI_PROCFS_POWER
1413 result = acpi_battery_add_fs(device);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001414 if (result) {
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001415 acpi_battery_remove_fs(device);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001416 goto fail;
1417 }
Bjørn Mork6993ce42017-12-05 18:46:39 +01001418#endif
Kyle McMartin25be5822011-03-22 16:19:50 -04001419
Dmitry Rozhkovdd1fca92018-07-24 14:27:33 +03001420 pr_info(PREFIX "%s Slot [%s] (battery %s)\n",
Stefan Hajnoczie80bba42011-07-12 09:03:28 +01001421 ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
1422 device->status.battery_present ? "present" : "absent");
1423
Kyle McMartin25be5822011-03-22 16:19:50 -04001424 battery->pm_nb.notifier_call = battery_notify;
1425 register_pm_notifier(&battery->pm_nb);
1426
Zhang Ruie0d1f092014-05-28 15:23:38 +08001427 device_init_wakeup(&device->dev, 1);
1428
Patrick Mocheld550d982006-06-27 00:41:40 -04001429 return result;
Stefan Hajnoczie80bba42011-07-12 09:03:28 +01001430
1431fail:
1432 sysfs_remove_battery(battery);
1433 mutex_destroy(&battery->lock);
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +03001434 mutex_destroy(&battery->sysfs_lock);
Stefan Hajnoczie80bba42011-07-12 09:03:28 +01001435 kfree(battery);
1436 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001437}
1438
Rafael J. Wysocki51fac832013-01-24 00:24:48 +01001439static int acpi_battery_remove(struct acpi_device *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001440{
Len Brown4be44fc2005-08-05 00:44:28 -04001441 struct acpi_battery *battery = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443 if (!device || !acpi_driver_data(device))
Patrick Mocheld550d982006-06-27 00:41:40 -04001444 return -EINVAL;
Zhang Ruie0d1f092014-05-28 15:23:38 +08001445 device_init_wakeup(&device->dev, 0);
Jan Engelhardt50dd0962006-10-01 00:28:50 +02001446 battery = acpi_driver_data(device);
Kyle McMartin25be5822011-03-22 16:19:50 -04001447 unregister_pm_notifier(&battery->pm_nb);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001448#ifdef CONFIG_ACPI_PROCFS_POWER
1449 acpi_battery_remove_fs(device);
1450#endif
Andrey Borzenkov508df922007-10-28 12:50:09 +03001451 sysfs_remove_battery(battery);
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +04001452 mutex_destroy(&battery->lock);
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +03001453 mutex_destroy(&battery->sysfs_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454 kfree(battery);
Patrick Mocheld550d982006-06-27 00:41:40 -04001455 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456}
1457
Rafael J. Wysocki90692402012-08-09 23:00:02 +02001458#ifdef CONFIG_PM_SLEEP
Jiri Kosina34c44152006-10-10 14:20:41 -07001459/* this is needed to learn about changes made in suspended state */
Rafael J. Wysockia6f50dc2012-06-27 23:26:43 +02001460static int acpi_battery_resume(struct device *dev)
Jiri Kosina34c44152006-10-10 14:20:41 -07001461{
1462 struct acpi_battery *battery;
Rafael J. Wysockia6f50dc2012-06-27 23:26:43 +02001463
1464 if (!dev)
Jiri Kosina34c44152006-10-10 14:20:41 -07001465 return -EINVAL;
Rafael J. Wysockia6f50dc2012-06-27 23:26:43 +02001466
1467 battery = acpi_driver_data(to_acpi_device(dev));
1468 if (!battery)
1469 return -EINVAL;
1470
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +04001471 battery->update_time = 0;
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001472 acpi_battery_update(battery, true);
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +03001473 return 0;
Jiri Kosina34c44152006-10-10 14:20:41 -07001474}
Shuah Khan7f6895c2014-02-12 20:19:06 -07001475#else
1476#define acpi_battery_resume NULL
Rafael J. Wysocki90692402012-08-09 23:00:02 +02001477#endif
Jiri Kosina34c44152006-10-10 14:20:41 -07001478
Rafael J. Wysockia6f50dc2012-06-27 23:26:43 +02001479static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume);
1480
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +04001481static struct acpi_driver acpi_battery_driver = {
1482 .name = "battery",
1483 .class = ACPI_BATTERY_CLASS,
1484 .ids = battery_device_ids,
Bjorn Helgaasd9406692009-04-30 09:35:47 -06001485 .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +04001486 .ops = {
1487 .add = acpi_battery_add,
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +04001488 .remove = acpi_battery_remove,
Bjorn Helgaasd9406692009-04-30 09:35:47 -06001489 .notify = acpi_battery_notify,
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +04001490 },
Rafael J. Wysockia6f50dc2012-06-27 23:26:43 +02001491 .drv.pm = &acpi_battery_pm,
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +04001492};
1493
Linus Torvaldsb0cbc862009-04-11 12:45:20 -07001494static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001495{
Hans de Goededccfae62017-04-19 14:02:10 +02001496 unsigned int i;
Luis Henriques479faaf2015-05-11 22:48:46 +01001497 int result;
1498
Alexander Mezin3f5dc082014-06-04 02:01:22 +07001499 dmi_check_system(bat_dmi_table);
Luis Henriques479faaf2015-05-11 22:48:46 +01001500
Carlo Caioneec625a32018-04-18 14:04:39 +02001501 if (battery_check_pmic) {
1502 for (i = 0; i < ARRAY_SIZE(acpi_battery_blacklist); i++)
1503 if (acpi_dev_present(acpi_battery_blacklist[i], "1", -1)) {
1504 pr_info(PREFIX ACPI_BATTERY_DEVICE_NAME
1505 ": found native %s PMIC, not loading\n",
1506 acpi_battery_blacklist[i]);
1507 return;
1508 }
1509 }
1510
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001511#ifdef CONFIG_ACPI_PROCFS_POWER
1512 acpi_battery_dir = acpi_lock_battery_dir();
1513 if (!acpi_battery_dir)
1514 return;
1515#endif
Luis Henriques479faaf2015-05-11 22:48:46 +01001516 result = acpi_bus_register_driver(&acpi_battery_driver);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001517#ifdef CONFIG_ACPI_PROCFS_POWER
Luis Henriques479faaf2015-05-11 22:48:46 +01001518 if (result < 0)
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001519 acpi_unlock_battery_dir(acpi_battery_dir);
1520#endif
Hans de Goedebc39fbc2017-04-19 14:02:09 +02001521 battery_driver_registered = (result == 0);
Arjan van de Ven0f66af52009-01-10 14:19:05 -05001522}
1523
1524static int __init acpi_battery_init(void)
1525{
Luis Henriquese234b072015-05-11 22:48:38 +01001526 if (acpi_disabled)
1527 return -ENODEV;
1528
Luis Henriqueseca21d912015-05-11 22:49:05 +01001529 async_cookie = async_schedule(acpi_battery_init_async, NULL);
Patrick Mocheld550d982006-06-27 00:41:40 -04001530 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531}
1532
Len Brown4be44fc2005-08-05 00:44:28 -04001533static void __exit acpi_battery_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534{
Chris Wilson5dfa0c72016-05-19 09:11:52 +01001535 async_synchronize_cookie(async_cookie + 1);
Ognjen Galicfa938542018-02-07 15:58:13 +01001536 if (battery_driver_registered) {
Hans de Goedebc39fbc2017-04-19 14:02:09 +02001537 acpi_bus_unregister_driver(&acpi_battery_driver);
Ognjen Galicfa938542018-02-07 15:58:13 +01001538 battery_hook_exit();
1539 }
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001540#ifdef CONFIG_ACPI_PROCFS_POWER
Hans de Goedebc39fbc2017-04-19 14:02:09 +02001541 if (acpi_battery_dir)
1542 acpi_unlock_battery_dir(acpi_battery_dir);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001543#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544}
1545
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546module_init(acpi_battery_init);
1547module_exit(acpi_battery_exit);