blob: b0113a5802a3c073f5787de456bc601f0f8c11cd [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;
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 Iskra4000e622012-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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367/* --------------------------------------------------------------------------
368 Battery Management
369 -------------------------------------------------------------------------- */
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400370struct acpi_offsets {
371 size_t offset; /* offset inside struct acpi_sbs_battery */
372 u8 mode; /* int or string? */
373};
374
Mathias Krausea4658782015-06-13 14:26:53 +0200375static const struct acpi_offsets state_offsets[] = {
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400376 {offsetof(struct acpi_battery, state), 0},
Alexey Starikovskiy7faa1442009-03-27 22:23:52 -0400377 {offsetof(struct acpi_battery, rate_now), 0},
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400378 {offsetof(struct acpi_battery, capacity_now), 0},
379 {offsetof(struct acpi_battery, voltage_now), 0},
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400380};
381
Mathias Krausea4658782015-06-13 14:26:53 +0200382static const struct acpi_offsets info_offsets[] = {
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400383 {offsetof(struct acpi_battery, power_unit), 0},
384 {offsetof(struct acpi_battery, design_capacity), 0},
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400385 {offsetof(struct acpi_battery, full_charge_capacity), 0},
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400386 {offsetof(struct acpi_battery, technology), 0},
387 {offsetof(struct acpi_battery, design_voltage), 0},
388 {offsetof(struct acpi_battery, design_capacity_warning), 0},
389 {offsetof(struct acpi_battery, design_capacity_low), 0},
390 {offsetof(struct acpi_battery, capacity_granularity_1), 0},
391 {offsetof(struct acpi_battery, capacity_granularity_2), 0},
392 {offsetof(struct acpi_battery, model_number), 1},
393 {offsetof(struct acpi_battery, serial_number), 1},
394 {offsetof(struct acpi_battery, type), 1},
395 {offsetof(struct acpi_battery, oem_info), 1},
396};
397
Mathias Krausea4658782015-06-13 14:26:53 +0200398static const struct acpi_offsets extended_info_offsets[] = {
Lan Tianyu016d5ba2013-07-30 14:00:42 +0200399 {offsetof(struct acpi_battery, revision), 0},
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400400 {offsetof(struct acpi_battery, power_unit), 0},
401 {offsetof(struct acpi_battery, design_capacity), 0},
402 {offsetof(struct acpi_battery, full_charge_capacity), 0},
403 {offsetof(struct acpi_battery, technology), 0},
404 {offsetof(struct acpi_battery, design_voltage), 0},
405 {offsetof(struct acpi_battery, design_capacity_warning), 0},
406 {offsetof(struct acpi_battery, design_capacity_low), 0},
407 {offsetof(struct acpi_battery, cycle_count), 0},
408 {offsetof(struct acpi_battery, measurement_accuracy), 0},
409 {offsetof(struct acpi_battery, max_sampling_time), 0},
410 {offsetof(struct acpi_battery, min_sampling_time), 0},
411 {offsetof(struct acpi_battery, max_averaging_interval), 0},
412 {offsetof(struct acpi_battery, min_averaging_interval), 0},
413 {offsetof(struct acpi_battery, capacity_granularity_1), 0},
414 {offsetof(struct acpi_battery, capacity_granularity_2), 0},
415 {offsetof(struct acpi_battery, model_number), 1},
416 {offsetof(struct acpi_battery, serial_number), 1},
417 {offsetof(struct acpi_battery, type), 1},
418 {offsetof(struct acpi_battery, oem_info), 1},
419};
420
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400421static int extract_package(struct acpi_battery *battery,
422 union acpi_object *package,
Mathias Krausea4658782015-06-13 14:26:53 +0200423 const struct acpi_offsets *offsets, int num)
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300424{
Alexey Starikovskiy106449e2007-10-29 23:29:40 +0300425 int i;
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400426 union acpi_object *element;
427 if (package->type != ACPI_TYPE_PACKAGE)
428 return -EFAULT;
429 for (i = 0; i < num; ++i) {
430 if (package->package.count <= i)
431 return -EFAULT;
432 element = &package->package.elements[i];
433 if (offsets[i].mode) {
Alexey Starikovskiy106449e2007-10-29 23:29:40 +0300434 u8 *ptr = (u8 *)battery + offsets[i].offset;
435 if (element->type == ACPI_TYPE_STRING ||
436 element->type == ACPI_TYPE_BUFFER)
437 strncpy(ptr, element->string.pointer, 32);
438 else if (element->type == ACPI_TYPE_INTEGER) {
439 strncpy(ptr, (u8 *)&element->integer.value,
Lin Ming439913f2010-01-28 10:53:19 +0800440 sizeof(u64));
441 ptr[sizeof(u64)] = 0;
Alexey Starikovskiyb8a1bdb2008-03-17 22:37:42 -0400442 } else
443 *ptr = 0; /* don't have value */
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400444 } else {
Alexey Starikovskiyb8a1bdb2008-03-17 22:37:42 -0400445 int *x = (int *)((u8 *)battery + offsets[i].offset);
446 *x = (element->type == ACPI_TYPE_INTEGER) ?
447 element->integer.value : -1;
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300448 }
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300449 }
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300450 return 0;
451}
452
453static int acpi_battery_get_status(struct acpi_battery *battery)
454{
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400455 if (acpi_bus_get_status(battery->device)) {
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300456 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA"));
457 return -ENODEV;
458 }
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400459 return 0;
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300460}
461
Dave Lambley2d09af42016-11-04 01:05:40 +0000462
463static int extract_battery_info(const int use_bix,
464 struct acpi_battery *battery,
465 const struct acpi_buffer *buffer)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466{
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400467 int result = -EFAULT;
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400468
Dave Lambley2d09af42016-11-04 01:05:40 +0000469 if (use_bix && battery_bix_broken_package)
470 result = extract_package(battery, buffer->pointer,
Lan Tianyua90b4032014-01-06 22:50:37 +0800471 extended_info_offsets + 1,
472 ARRAY_SIZE(extended_info_offsets) - 1);
Dave Lambley2d09af42016-11-04 01:05:40 +0000473 else if (use_bix)
474 result = extract_package(battery, buffer->pointer,
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400475 extended_info_offsets,
476 ARRAY_SIZE(extended_info_offsets));
477 else
Dave Lambley2d09af42016-11-04 01:05:40 +0000478 result = extract_package(battery, buffer->pointer,
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400479 info_offsets, ARRAY_SIZE(info_offsets));
Zhang Rui557d5862010-10-22 10:02:06 +0800480 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
481 battery->full_charge_capacity = battery->design_capacity;
Kamil Iskra4000e622012-11-16 22:28:58 +0100482 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) &&
483 battery->power_unit && battery->design_voltage) {
484 battery->design_capacity = battery->design_capacity *
485 10000 / battery->design_voltage;
486 battery->full_charge_capacity = battery->full_charge_capacity *
487 10000 / battery->design_voltage;
488 battery->design_capacity_warning =
489 battery->design_capacity_warning *
490 10000 / battery->design_voltage;
491 /* Curiously, design_capacity_low, unlike the rest of them,
492 is correct. */
493 /* capacity_granularity_* equal 1 on the systems tested, so
494 it's impossible to tell if they would need an adjustment
495 or not if their values were higher. */
496 }
Laszlo Totha20136a2018-02-24 10:20:15 +0100497 if (test_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags) &&
498 battery->capacity_now > battery->full_charge_capacity)
499 battery->capacity_now = battery->full_charge_capacity;
500
Patrick Mocheld550d982006-06-27 00:41:40 -0400501 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502}
503
Dave Lambley2d09af42016-11-04 01:05:40 +0000504static int acpi_battery_get_info(struct acpi_battery *battery)
505{
506 const int xinfo = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
507 int use_bix;
508 int result = -ENODEV;
509
510 if (!acpi_battery_present(battery))
511 return 0;
512
513
514 for (use_bix = xinfo ? 1 : 0; use_bix >= 0; use_bix--) {
515 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
516 acpi_status status = AE_ERROR;
517
518 mutex_lock(&battery->lock);
519 status = acpi_evaluate_object(battery->device->handle,
520 use_bix ? "_BIX":"_BIF",
521 NULL, &buffer);
522 mutex_unlock(&battery->lock);
523
524 if (ACPI_FAILURE(status)) {
525 ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s",
526 use_bix ? "_BIX":"_BIF"));
527 } else {
528 result = extract_battery_info(use_bix,
529 battery,
530 &buffer);
531
532 kfree(buffer.pointer);
533 break;
534 }
535 }
536
537 if (!result && !use_bix && xinfo)
538 pr_warn(FW_BUG "The _BIX method is broken, using _BIF.\n");
539
540 return result;
541}
542
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300543static int acpi_battery_get_state(struct acpi_battery *battery)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544{
Len Brown4be44fc2005-08-05 00:44:28 -0400545 int result = 0;
546 acpi_status status = 0;
547 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300549 if (!acpi_battery_present(battery))
550 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400552 if (battery->update_time &&
553 time_before(jiffies, battery->update_time +
554 msecs_to_jiffies(cache_time)))
555 return 0;
556
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400557 mutex_lock(&battery->lock);
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400558 status = acpi_evaluate_object(battery->device->handle, "_BST",
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400559 NULL, &buffer);
560 mutex_unlock(&battery->lock);
Len Brown5b31d892007-08-15 00:19:26 -0400561
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562 if (ACPI_FAILURE(status)) {
Thomas Renningera6fc6722006-06-26 23:58:43 -0400563 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
Patrick Mocheld550d982006-06-27 00:41:40 -0400564 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700565 }
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400566
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400567 result = extract_package(battery, buffer.pointer,
568 state_offsets, ARRAY_SIZE(state_offsets));
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400569 battery->update_time = jiffies;
Alexey Starikovskiy78490d82007-05-11 13:18:55 -0400570 kfree(buffer.pointer);
Hector Martinbc76f902009-08-06 15:57:48 -0700571
Lan Tianyu55003b22011-06-30 11:33:12 +0800572 /* For buggy DSDTs that report negative 16-bit values for either
573 * charging or discharging current and/or report 0 as 65536
574 * due to bad math.
575 */
576 if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA &&
577 battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN &&
578 (s16)(battery->rate_now) < 0) {
Hector Martinbc76f902009-08-06 15:57:48 -0700579 battery->rate_now = abs((s16)battery->rate_now);
Martin Kepplinger92375162015-03-13 00:48:17 +0100580 printk_once(KERN_WARNING FW_BUG
581 "battery: (dis)charge rate invalid.\n");
Lan Tianyu55003b22011-06-30 11:33:12 +0800582 }
Hector Martinbc76f902009-08-06 15:57:48 -0700583
Zhang Rui557d5862010-10-22 10:02:06 +0800584 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
585 && battery->capacity_now >= 0 && battery->capacity_now <= 100)
586 battery->capacity_now = (battery->capacity_now *
587 battery->full_charge_capacity) / 100;
Kamil Iskra4000e622012-11-16 22:28:58 +0100588 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) &&
589 battery->power_unit && battery->design_voltage) {
590 battery->capacity_now = battery->capacity_now *
591 10000 / battery->design_voltage;
592 }
Laszlo Totha20136a2018-02-24 10:20:15 +0100593 if (test_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags) &&
594 battery->capacity_now > battery->full_charge_capacity)
595 battery->capacity_now = battery->full_charge_capacity;
596
Patrick Mocheld550d982006-06-27 00:41:40 -0400597 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598}
599
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400600static int acpi_battery_set_alarm(struct acpi_battery *battery)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700601{
Len Brown4be44fc2005-08-05 00:44:28 -0400602 acpi_status status = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400604 if (!acpi_battery_present(battery) ||
Alexey Starikovskiy7b3bcc42009-10-15 14:31:24 +0400605 !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags))
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300606 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400608 mutex_lock(&battery->lock);
Jiang Liu0db98202013-06-29 00:24:39 +0800609 status = acpi_execute_simple_method(battery->device->handle, "_BTP",
610 battery->alarm);
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400611 mutex_unlock(&battery->lock);
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400612
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613 if (ACPI_FAILURE(status))
Patrick Mocheld550d982006-06-27 00:41:40 -0400614 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400616 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", battery->alarm));
Patrick Mocheld550d982006-06-27 00:41:40 -0400617 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618}
619
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300620static int acpi_battery_init_alarm(struct acpi_battery *battery)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621{
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300622 /* See if alarms are supported, and if so, set default */
Jiang Liu952c63e2013-06-29 00:24:38 +0800623 if (!acpi_has_method(battery->device->handle, "_BTP")) {
Alexey Starikovskiy7b3bcc42009-10-15 14:31:24 +0400624 clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400625 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626 }
Alexey Starikovskiy7b3bcc42009-10-15 14:31:24 +0400627 set_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400628 if (!battery->alarm)
629 battery->alarm = battery->design_capacity_warning;
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400630 return acpi_battery_set_alarm(battery);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631}
632
Andrey Borzenkov508df922007-10-28 12:50:09 +0300633static ssize_t acpi_battery_alarm_show(struct device *dev,
634 struct device_attribute *attr,
635 char *buf)
636{
637 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
638 return sprintf(buf, "%d\n", battery->alarm * 1000);
639}
640
641static ssize_t acpi_battery_alarm_store(struct device *dev,
642 struct device_attribute *attr,
643 const char *buf, size_t count)
644{
645 unsigned long x;
646 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
Luis G.F47a08c82014-01-21 15:40:43 +0100647 if (sscanf(buf, "%lu\n", &x) == 1)
Andrey Borzenkov508df922007-10-28 12:50:09 +0300648 battery->alarm = x/1000;
649 if (acpi_battery_present(battery))
650 acpi_battery_set_alarm(battery);
651 return count;
652}
653
Bhumika Goyal82d2b612017-08-21 17:13:07 +0530654static const struct device_attribute alarm_attr = {
Parag Warudkar01e8ef12008-10-18 20:28:50 -0700655 .attr = {.name = "alarm", .mode = 0644},
Andrey Borzenkov508df922007-10-28 12:50:09 +0300656 .show = acpi_battery_alarm_show,
657 .store = acpi_battery_alarm_store,
658};
659
Ognjen Galicfa938542018-02-07 15:58:13 +0100660/*
661 * The Battery Hooking API
662 *
663 * This API is used inside other drivers that need to expose
664 * platform-specific behaviour within the generic driver in a
665 * generic way.
666 *
667 */
668
669static LIST_HEAD(acpi_battery_list);
670static LIST_HEAD(battery_hook_list);
671static DEFINE_MUTEX(hook_mutex);
672
Colin Ian King514bcc52018-02-23 16:32:55 +0000673static void __battery_hook_unregister(struct acpi_battery_hook *hook, int lock)
Ognjen Galicfa938542018-02-07 15:58:13 +0100674{
675 struct acpi_battery *battery;
676 /*
677 * In order to remove a hook, we first need to
678 * de-register all the batteries that are registered.
679 */
680 if (lock)
681 mutex_lock(&hook_mutex);
682 list_for_each_entry(battery, &acpi_battery_list, list) {
683 hook->remove_battery(battery->bat);
684 }
685 list_del(&hook->list);
686 if (lock)
687 mutex_unlock(&hook_mutex);
688 pr_info("extension unregistered: %s\n", hook->name);
689}
690
691void battery_hook_unregister(struct acpi_battery_hook *hook)
692{
693 __battery_hook_unregister(hook, 1);
694}
695EXPORT_SYMBOL_GPL(battery_hook_unregister);
696
697void battery_hook_register(struct acpi_battery_hook *hook)
698{
699 struct acpi_battery *battery;
700
701 mutex_lock(&hook_mutex);
702 INIT_LIST_HEAD(&hook->list);
703 list_add(&hook->list, &battery_hook_list);
704 /*
705 * Now that the driver is registered, we need
706 * to notify the hook that a battery is available
707 * for each battery, so that the driver may add
708 * its attributes.
709 */
710 list_for_each_entry(battery, &acpi_battery_list, list) {
711 if (hook->add_battery(battery->bat)) {
712 /*
713 * If a add-battery returns non-zero,
714 * the registration of the extension has failed,
715 * and we will not add it to the list of loaded
716 * hooks.
717 */
718 pr_err("extension failed to load: %s", hook->name);
719 __battery_hook_unregister(hook, 0);
720 return;
721 }
722 }
723 pr_info("new extension: %s\n", hook->name);
724 mutex_unlock(&hook_mutex);
725}
726EXPORT_SYMBOL_GPL(battery_hook_register);
727
728/*
729 * This function gets called right after the battery sysfs
730 * attributes have been added, so that the drivers that
731 * define custom sysfs attributes can add their own.
Rafael J. Wysocki7a4ea102018-03-13 10:07:49 +0100732*/
Ognjen Galicfa938542018-02-07 15:58:13 +0100733static void battery_hook_add_battery(struct acpi_battery *battery)
734{
735 struct acpi_battery_hook *hook_node;
736
737 mutex_lock(&hook_mutex);
738 INIT_LIST_HEAD(&battery->list);
739 list_add(&battery->list, &acpi_battery_list);
740 /*
741 * Since we added a new battery to the list, we need to
742 * iterate over the hooks and call add_battery for each
743 * hook that was registered. This usually happens
744 * when a battery gets hotplugged or initialized
745 * during the battery module initialization.
746 */
747 list_for_each_entry(hook_node, &battery_hook_list, list) {
748 if (hook_node->add_battery(battery->bat)) {
749 /*
750 * The notification of the extensions has failed, to
751 * prevent further errors we will unload the extension.
752 */
753 __battery_hook_unregister(hook_node, 0);
754 pr_err("error in extension, unloading: %s",
755 hook_node->name);
756 }
757 }
758 mutex_unlock(&hook_mutex);
759}
760
761static void battery_hook_remove_battery(struct acpi_battery *battery)
762{
763 struct acpi_battery_hook *hook;
764
765 mutex_lock(&hook_mutex);
766 /*
767 * Before removing the hook, we need to remove all
768 * custom attributes from the battery.
769 */
770 list_for_each_entry(hook, &battery_hook_list, list) {
771 hook->remove_battery(battery->bat);
772 }
773 /* Then, just remove the battery from the list */
774 list_del(&battery->list);
775 mutex_unlock(&hook_mutex);
776}
777
778static void __exit battery_hook_exit(void)
779{
780 struct acpi_battery_hook *hook;
781 struct acpi_battery_hook *ptr;
782 /*
783 * At this point, the acpi_bus_unregister_driver()
784 * has called remove for all batteries. We just
785 * need to remove the hooks.
786 */
787 list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) {
788 __battery_hook_unregister(hook, 1);
789 }
790 mutex_destroy(&hook_mutex);
791}
792
Andrey Borzenkov508df922007-10-28 12:50:09 +0300793static int sysfs_add_battery(struct acpi_battery *battery)
794{
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100795 struct power_supply_config psy_cfg = { .drv_data = battery, };
Andrey Borzenkov508df922007-10-28 12:50:09 +0300796
Lan Tianyuae6f6182011-06-30 11:32:40 +0800797 if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) {
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100798 battery->bat_desc.properties = charge_battery_props;
799 battery->bat_desc.num_properties =
Andrey Borzenkov508df922007-10-28 12:50:09 +0300800 ARRAY_SIZE(charge_battery_props);
801 } else {
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100802 battery->bat_desc.properties = energy_battery_props;
803 battery->bat_desc.num_properties =
Andrey Borzenkov508df922007-10-28 12:50:09 +0300804 ARRAY_SIZE(energy_battery_props);
805 }
806
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100807 battery->bat_desc.name = acpi_device_bid(battery->device);
808 battery->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY;
809 battery->bat_desc.get_property = acpi_battery_get_property;
Andrey Borzenkov508df922007-10-28 12:50:09 +0300810
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100811 battery->bat = power_supply_register_no_ws(&battery->device->dev,
812 &battery->bat_desc, &psy_cfg);
Zhang Ruie0d1f092014-05-28 15:23:38 +0800813
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100814 if (IS_ERR(battery->bat)) {
815 int result = PTR_ERR(battery->bat);
816
817 battery->bat = NULL;
Andrey Borzenkov508df922007-10-28 12:50:09 +0300818 return result;
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100819 }
Ognjen Galicfa938542018-02-07 15:58:13 +0100820 battery_hook_add_battery(battery);
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100821 return device_create_file(&battery->bat->dev, &alarm_attr);
Andrey Borzenkov508df922007-10-28 12:50:09 +0300822}
823
824static void sysfs_remove_battery(struct acpi_battery *battery)
825{
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +0300826 mutex_lock(&battery->sysfs_lock);
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100827 if (!battery->bat) {
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +0300828 mutex_unlock(&battery->sysfs_lock);
Andrey Borzenkov508df922007-10-28 12:50:09 +0300829 return;
Lan Tianyu9c921c222011-06-30 11:34:12 +0800830 }
Ognjen Galicfa938542018-02-07 15:58:13 +0100831 battery_hook_remove_battery(battery);
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100832 device_remove_file(&battery->bat->dev, &alarm_attr);
833 power_supply_unregister(battery->bat);
834 battery->bat = NULL;
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +0300835 mutex_unlock(&battery->sysfs_lock);
Hector Martinbc76f902009-08-06 15:57:48 -0700836}
837
Kamil Iskra4000e622012-11-16 22:28:58 +0100838static void find_battery(const struct dmi_header *dm, void *private)
839{
840 struct acpi_battery *battery = (struct acpi_battery *)private;
841 /* Note: the hardcoded offsets below have been extracted from
842 the source code of dmidecode. */
843 if (dm->type == DMI_ENTRY_PORTABLE_BATTERY && dm->length >= 8) {
844 const u8 *dmi_data = (const u8 *)(dm + 1);
845 int dmi_capacity = get_unaligned((const u16 *)(dmi_data + 6));
846 if (dm->length >= 18)
847 dmi_capacity *= dmi_data[17];
848 if (battery->design_capacity * battery->design_voltage / 1000
849 != dmi_capacity &&
850 battery->design_capacity * 10 == dmi_capacity)
851 set_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH,
852 &battery->flags);
853 }
854}
855
Zhang Rui557d5862010-10-22 10:02:06 +0800856/*
857 * According to the ACPI spec, some kinds of primary batteries can
858 * report percentage battery remaining capacity directly to OS.
859 * In this case, it reports the Last Full Charged Capacity == 100
860 * and BatteryPresentRate == 0xFFFFFFFF.
861 *
862 * Now we found some battery reports percentage remaining capacity
863 * even if it's rechargeable.
864 * https://bugzilla.kernel.org/show_bug.cgi?id=15979
865 *
866 * Handle this correctly so that they won't break userspace.
867 */
Lan Tianyu7b786222011-06-30 11:33:27 +0800868static void acpi_battery_quirks(struct acpi_battery *battery)
Zhang Rui557d5862010-10-22 10:02:06 +0800869{
870 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
Nicholas Mazzuca0f4c6542013-05-08 23:11:15 +0000871 return;
Zhang Rui557d5862010-10-22 10:02:06 +0800872
Nicholas Mazzuca0f4c6542013-05-08 23:11:15 +0000873 if (battery->full_charge_capacity == 100 &&
874 battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
875 battery->capacity_now >= 0 && battery->capacity_now <= 100) {
Zhang Rui557d5862010-10-22 10:02:06 +0800876 set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags);
877 battery->full_charge_capacity = battery->design_capacity;
878 battery->capacity_now = (battery->capacity_now *
879 battery->full_charge_capacity) / 100;
880 }
Kamil Iskra4000e622012-11-16 22:28:58 +0100881
882 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags))
Nicholas Mazzuca0f4c6542013-05-08 23:11:15 +0000883 return;
Kamil Iskra4000e622012-11-16 22:28:58 +0100884
885 if (battery->power_unit && dmi_name_in_vendors("LENOVO")) {
886 const char *s;
887 s = dmi_get_system_info(DMI_PRODUCT_VERSION);
Rasmus Villemoesffd8a732014-09-16 22:51:24 +0200888 if (s && !strncasecmp(s, "ThinkPad", 8)) {
Kamil Iskra4000e622012-11-16 22:28:58 +0100889 dmi_walk(find_battery, battery);
890 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH,
891 &battery->flags) &&
892 battery->design_voltage) {
893 battery->design_capacity =
894 battery->design_capacity *
895 10000 / battery->design_voltage;
896 battery->full_charge_capacity =
897 battery->full_charge_capacity *
898 10000 / battery->design_voltage;
899 battery->design_capacity_warning =
900 battery->design_capacity_warning *
901 10000 / battery->design_voltage;
902 battery->capacity_now = battery->capacity_now *
903 10000 / battery->design_voltage;
904 }
905 }
906 }
Laszlo Totha20136a2018-02-24 10:20:15 +0100907
908 if (test_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags))
909 return;
910
911 if (acpi_battery_is_degraded(battery) &&
912 battery->capacity_now > battery->full_charge_capacity) {
913 set_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags);
914 battery->capacity_now = battery->full_charge_capacity;
915 }
Zhang Rui557d5862010-10-22 10:02:06 +0800916}
917
Lan Tianyu9e50bc12014-05-04 14:07:06 +0800918static int acpi_battery_update(struct acpi_battery *battery, bool resume)
Vladimir Lebedev4bd35cd2007-02-10 01:43:48 -0500919{
Alexey Starikovskiy50b17852008-12-23 02:44:54 +0300920 int result, old_present = acpi_battery_present(battery);
Alexey Starikovskiy97749cd2008-01-01 14:27:24 -0500921 result = acpi_battery_get_status(battery);
Andrey Borzenkov508df922007-10-28 12:50:09 +0300922 if (result)
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300923 return result;
Andrey Borzenkov508df922007-10-28 12:50:09 +0300924 if (!acpi_battery_present(battery)) {
925 sysfs_remove_battery(battery);
Alexey Starikovskiy97749cd2008-01-01 14:27:24 -0500926 battery->update_time = 0;
Andrey Borzenkov508df922007-10-28 12:50:09 +0300927 return 0;
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300928 }
Lan Tianyu9e50bc12014-05-04 14:07:06 +0800929
930 if (resume)
931 return 0;
932
Alexey Starikovskiy50b17852008-12-23 02:44:54 +0300933 if (!battery->update_time ||
934 old_present != acpi_battery_present(battery)) {
Alexey Starikovskiy97749cd2008-01-01 14:27:24 -0500935 result = acpi_battery_get_info(battery);
936 if (result)
937 return result;
938 acpi_battery_init_alarm(battery);
939 }
Carlos Garnacho12c78ca2016-08-10 17:24:15 +0200940
941 result = acpi_battery_get_state(battery);
942 if (result)
943 return result;
944 acpi_battery_quirks(battery);
945
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100946 if (!battery->bat) {
Stefan Hajnoczieb03cb02011-07-12 09:03:29 +0100947 result = sysfs_add_battery(battery);
948 if (result)
949 return result;
950 }
Zhang Ruie0d1f092014-05-28 15:23:38 +0800951
952 /*
953 * Wakeup the system if battery is critical low
954 * or lower than the alarm level
955 */
956 if ((battery->state & ACPI_BATTERY_STATE_CRITICAL) ||
957 (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) &&
958 (battery->capacity_now <= battery->alarm)))
Rafael J. Wysocki33e4f802017-06-12 22:56:34 +0200959 acpi_pm_wakeup_event(&battery->device->dev);
Zhang Ruie0d1f092014-05-28 15:23:38 +0800960
Zhang Rui557d5862010-10-22 10:02:06 +0800961 return result;
Vladimir Lebedev4bd35cd2007-02-10 01:43:48 -0500962}
963
Rafael J. Wysockida8aeb92011-01-06 23:42:27 +0100964static void acpi_battery_refresh(struct acpi_battery *battery)
965{
Andy Whitcroftc5971452012-05-03 14:48:26 +0100966 int power_unit;
967
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100968 if (!battery->bat)
Rafael J. Wysockida8aeb92011-01-06 23:42:27 +0100969 return;
970
Andy Whitcroftc5971452012-05-03 14:48:26 +0100971 power_unit = battery->power_unit;
972
Rafael J. Wysockida8aeb92011-01-06 23:42:27 +0100973 acpi_battery_get_info(battery);
Andy Whitcroftc5971452012-05-03 14:48:26 +0100974
975 if (power_unit == battery->power_unit)
976 return;
977
978 /* The battery has changed its reporting units. */
Rafael J. Wysockida8aeb92011-01-06 23:42:27 +0100979 sysfs_remove_battery(battery);
980 sysfs_add_battery(battery);
981}
982
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983/* --------------------------------------------------------------------------
Lan Tianyu3a670cc2014-05-04 11:07:25 +0800984 FS Interface (/proc)
985 -------------------------------------------------------------------------- */
986
987#ifdef CONFIG_ACPI_PROCFS_POWER
988static struct proc_dir_entry *acpi_battery_dir;
989
Mathias Krause27059b92015-06-13 14:26:54 +0200990static const char *acpi_battery_units(const struct acpi_battery *battery)
991{
992 return (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) ?
993 "mA" : "mW";
994}
995
Christoph Hellwige7b087f2018-04-11 16:27:14 +0200996static int acpi_battery_info_proc_show(struct seq_file *seq, void *offset)
Lan Tianyu3a670cc2014-05-04 11:07:25 +0800997{
998 struct acpi_battery *battery = seq->private;
Christoph Hellwige7b087f2018-04-11 16:27:14 +0200999 int result = acpi_battery_update(battery, false);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001000
1001 if (result)
1002 goto end;
1003
1004 seq_printf(seq, "present: %s\n",
1005 acpi_battery_present(battery) ? "yes" : "no");
1006 if (!acpi_battery_present(battery))
1007 goto end;
1008 if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
1009 seq_printf(seq, "design capacity: unknown\n");
1010 else
1011 seq_printf(seq, "design capacity: %d %sh\n",
1012 battery->design_capacity,
1013 acpi_battery_units(battery));
1014
1015 if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
1016 seq_printf(seq, "last full capacity: unknown\n");
1017 else
1018 seq_printf(seq, "last full capacity: %d %sh\n",
1019 battery->full_charge_capacity,
1020 acpi_battery_units(battery));
1021
1022 seq_printf(seq, "battery technology: %srechargeable\n",
1023 (!battery->technology)?"non-":"");
1024
1025 if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
1026 seq_printf(seq, "design voltage: unknown\n");
1027 else
1028 seq_printf(seq, "design voltage: %d mV\n",
1029 battery->design_voltage);
1030 seq_printf(seq, "design capacity warning: %d %sh\n",
1031 battery->design_capacity_warning,
1032 acpi_battery_units(battery));
1033 seq_printf(seq, "design capacity low: %d %sh\n",
1034 battery->design_capacity_low,
1035 acpi_battery_units(battery));
1036 seq_printf(seq, "cycle count: %i\n", battery->cycle_count);
1037 seq_printf(seq, "capacity granularity 1: %d %sh\n",
1038 battery->capacity_granularity_1,
1039 acpi_battery_units(battery));
1040 seq_printf(seq, "capacity granularity 2: %d %sh\n",
1041 battery->capacity_granularity_2,
1042 acpi_battery_units(battery));
1043 seq_printf(seq, "model number: %s\n", battery->model_number);
1044 seq_printf(seq, "serial number: %s\n", battery->serial_number);
1045 seq_printf(seq, "battery type: %s\n", battery->type);
1046 seq_printf(seq, "OEM info: %s\n", battery->oem_info);
1047 end:
1048 if (result)
1049 seq_printf(seq, "ERROR: Unable to read battery info\n");
1050 return result;
1051}
1052
Christoph Hellwige7b087f2018-04-11 16:27:14 +02001053static int acpi_battery_state_proc_show(struct seq_file *seq, void *offset)
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001054{
1055 struct acpi_battery *battery = seq->private;
Christoph Hellwige7b087f2018-04-11 16:27:14 +02001056 int result = acpi_battery_update(battery, false);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001057
1058 if (result)
1059 goto end;
1060
1061 seq_printf(seq, "present: %s\n",
1062 acpi_battery_present(battery) ? "yes" : "no");
1063 if (!acpi_battery_present(battery))
1064 goto end;
1065
1066 seq_printf(seq, "capacity state: %s\n",
1067 (battery->state & 0x04) ? "critical" : "ok");
1068 if ((battery->state & 0x01) && (battery->state & 0x02))
1069 seq_printf(seq,
1070 "charging state: charging/discharging\n");
1071 else if (battery->state & 0x01)
1072 seq_printf(seq, "charging state: discharging\n");
1073 else if (battery->state & 0x02)
1074 seq_printf(seq, "charging state: charging\n");
1075 else
1076 seq_printf(seq, "charging state: charged\n");
1077
1078 if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
1079 seq_printf(seq, "present rate: unknown\n");
1080 else
1081 seq_printf(seq, "present rate: %d %s\n",
1082 battery->rate_now, acpi_battery_units(battery));
1083
1084 if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
1085 seq_printf(seq, "remaining capacity: unknown\n");
1086 else
1087 seq_printf(seq, "remaining capacity: %d %sh\n",
1088 battery->capacity_now, acpi_battery_units(battery));
1089 if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
1090 seq_printf(seq, "present voltage: unknown\n");
1091 else
1092 seq_printf(seq, "present voltage: %d mV\n",
1093 battery->voltage_now);
1094 end:
1095 if (result)
1096 seq_printf(seq, "ERROR: Unable to read battery state\n");
1097
1098 return result;
1099}
1100
Christoph Hellwige7b087f2018-04-11 16:27:14 +02001101static int acpi_battery_alarm_proc_show(struct seq_file *seq, void *offset)
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001102{
1103 struct acpi_battery *battery = seq->private;
Christoph Hellwige7b087f2018-04-11 16:27:14 +02001104 int result = acpi_battery_update(battery, false);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001105
1106 if (result)
1107 goto end;
1108
1109 if (!acpi_battery_present(battery)) {
1110 seq_printf(seq, "present: no\n");
1111 goto end;
1112 }
1113 seq_printf(seq, "alarm: ");
1114 if (!battery->alarm)
1115 seq_printf(seq, "unsupported\n");
1116 else
1117 seq_printf(seq, "%u %sh\n", battery->alarm,
1118 acpi_battery_units(battery));
1119 end:
1120 if (result)
1121 seq_printf(seq, "ERROR: Unable to read battery alarm\n");
1122 return result;
1123}
1124
1125static ssize_t acpi_battery_write_alarm(struct file *file,
1126 const char __user * buffer,
1127 size_t count, loff_t * ppos)
1128{
1129 int result = 0;
1130 char alarm_string[12] = { '\0' };
1131 struct seq_file *m = file->private_data;
1132 struct acpi_battery *battery = m->private;
1133
1134 if (!battery || (count > sizeof(alarm_string) - 1))
1135 return -EINVAL;
1136 if (!acpi_battery_present(battery)) {
1137 result = -ENODEV;
1138 goto end;
1139 }
1140 if (copy_from_user(alarm_string, buffer, count)) {
1141 result = -EFAULT;
1142 goto end;
1143 }
1144 alarm_string[count] = '\0';
Christoph Jaeger3d915892014-06-13 21:49:58 +02001145 if (kstrtoint(alarm_string, 0, &battery->alarm)) {
1146 result = -EINVAL;
1147 goto end;
1148 }
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001149 result = acpi_battery_set_alarm(battery);
1150 end:
1151 if (!result)
1152 return count;
1153 return result;
1154}
1155
Christoph Hellwige7b087f2018-04-11 16:27:14 +02001156static int acpi_battery_alarm_proc_open(struct inode *inode, struct file *file)
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001157{
Christoph Hellwige7b087f2018-04-11 16:27:14 +02001158 return single_open(file, acpi_battery_alarm_proc_show, PDE_DATA(inode));
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001159}
1160
Christoph Hellwige7b087f2018-04-11 16:27:14 +02001161static const struct file_operations acpi_battery_alarm_fops = {
1162 .owner = THIS_MODULE,
1163 .open = acpi_battery_alarm_proc_open,
1164 .read = seq_read,
1165 .write = acpi_battery_write_alarm,
1166 .llseek = seq_lseek,
1167 .release = single_release,
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001168};
1169
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001170static int acpi_battery_add_fs(struct acpi_device *device)
1171{
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001172 printk(KERN_WARNING PREFIX "Deprecated procfs I/F for battery is loaded,"
1173 " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n");
1174 if (!acpi_device_dir(device)) {
1175 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
1176 acpi_battery_dir);
1177 if (!acpi_device_dir(device))
1178 return -ENODEV;
1179 }
1180
Christoph Hellwige7b087f2018-04-11 16:27:14 +02001181 if (!proc_create_single_data("info", S_IRUGO, acpi_device_dir(device),
1182 acpi_battery_info_proc_show, acpi_driver_data(device)))
1183 return -ENODEV;
1184 if (!proc_create_single_data("state", S_IRUGO, acpi_device_dir(device),
1185 acpi_battery_state_proc_show, acpi_driver_data(device)))
1186 return -ENODEV;
1187 if (!proc_create_data("alarm", S_IFREG | S_IRUGO | S_IWUSR,
1188 acpi_device_dir(device), &acpi_battery_alarm_fops,
1189 acpi_driver_data(device)))
1190 return -ENODEV;
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001191 return 0;
1192}
1193
1194static void acpi_battery_remove_fs(struct acpi_device *device)
1195{
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001196 if (!acpi_device_dir(device))
1197 return;
Christoph Hellwige7b087f2018-04-11 16:27:14 +02001198 remove_proc_subtree(acpi_device_bid(device), acpi_battery_dir);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001199 acpi_device_dir(device) = NULL;
1200}
1201
1202#endif
1203
1204/* --------------------------------------------------------------------------
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205 Driver Interface
1206 -------------------------------------------------------------------------- */
1207
Bjorn Helgaasd9406692009-04-30 09:35:47 -06001208static void acpi_battery_notify(struct acpi_device *device, u32 event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209{
Bjorn Helgaasd9406692009-04-30 09:35:47 -06001210 struct acpi_battery *battery = acpi_driver_data(device);
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +01001211 struct power_supply *old;
Bjorn Helgaasd9406692009-04-30 09:35:47 -06001212
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213 if (!battery)
Patrick Mocheld550d982006-06-27 00:41:40 -04001214 return;
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +01001215 old = battery->bat;
Alexander Mezinf43691c2014-06-04 02:01:23 +07001216 /*
1217 * On Acer Aspire V5-573G notifications are sometimes triggered too
1218 * early. For example, when AC is unplugged and notification is
1219 * triggered, battery state is still reported as "Full", and changes to
1220 * "Discharging" only after short delay, without any notification.
1221 */
1222 if (battery_notification_delay_ms > 0)
1223 msleep(battery_notification_delay_ms);
Rafael J. Wysockida8aeb92011-01-06 23:42:27 +01001224 if (event == ACPI_BATTERY_NOTIFY_INFO)
1225 acpi_battery_refresh(battery);
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001226 acpi_battery_update(battery, false);
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +04001227 acpi_bus_generate_netlink_event(device->pnp.device_class,
Kay Sievers07944692008-10-30 01:18:59 +01001228 dev_name(&device->dev), event,
Vladimir Lebedev9ea7d572007-02-20 15:48:06 +03001229 acpi_battery_present(battery));
Alexander Mezin411e0f72014-03-12 00:58:47 +07001230 acpi_notifier_call_chain(device, event, acpi_battery_present(battery));
Justin P. Mattock2345baf2009-12-13 14:42:36 -08001231 /* acpi_battery_update could remove power_supply object */
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +01001232 if (old && battery->bat)
1233 power_supply_changed(battery->bat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001234}
1235
Kyle McMartin25be5822011-03-22 16:19:50 -04001236static int battery_notify(struct notifier_block *nb,
1237 unsigned long mode, void *_unused)
1238{
1239 struct acpi_battery *battery = container_of(nb, struct acpi_battery,
1240 pm_nb);
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001241 int result;
1242
Kyle McMartin25be5822011-03-22 16:19:50 -04001243 switch (mode) {
Lan Tianyud5a59112011-06-30 11:33:40 +08001244 case PM_POST_HIBERNATION:
Kyle McMartin25be5822011-03-22 16:19:50 -04001245 case PM_POST_SUSPEND:
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001246 if (!acpi_battery_present(battery))
1247 return 0;
1248
Krzysztof Kozlowski31f7dc72015-04-14 22:24:13 +09001249 if (!battery->bat) {
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001250 result = acpi_battery_get_info(battery);
1251 if (result)
1252 return result;
1253
1254 result = sysfs_add_battery(battery);
1255 if (result)
1256 return result;
1257 } else
1258 acpi_battery_refresh(battery);
1259
1260 acpi_battery_init_alarm(battery);
1261 acpi_battery_get_state(battery);
Kyle McMartin25be5822011-03-22 16:19:50 -04001262 break;
1263 }
1264
1265 return 0;
1266}
1267
Mathias Krause048d16d2015-06-13 14:26:55 +02001268static int __init
1269battery_bix_broken_package_quirk(const struct dmi_system_id *d)
Alexander Mezin3f5dc082014-06-04 02:01:22 +07001270{
1271 battery_bix_broken_package = 1;
1272 return 0;
1273}
1274
Mathias Krause048d16d2015-06-13 14:26:55 +02001275static int __init
1276battery_notification_delay_quirk(const struct dmi_system_id *d)
Alexander Mezinf43691c2014-06-04 02:01:23 +07001277{
1278 battery_notification_delay_ms = 1000;
1279 return 0;
1280}
1281
Hans de Goede1b799c52018-04-12 12:02:00 +02001282static int __init
1283battery_ac_is_broken_quirk(const struct dmi_system_id *d)
1284{
1285 battery_ac_is_broken = 1;
1286 return 0;
1287}
1288
Carlo Caioneec625a32018-04-18 14:04:39 +02001289static int __init
1290battery_do_not_check_pmic_quirk(const struct dmi_system_id *d)
1291{
1292 battery_check_pmic = 0;
1293 return 0;
1294}
1295
Mathias Krause048d16d2015-06-13 14:26:55 +02001296static const struct dmi_system_id bat_dmi_table[] __initconst = {
Lan Tianyua90b4032014-01-06 22:50:37 +08001297 {
Hans de Goede91afa072018-04-12 12:01:58 +02001298 /* NEC LZ750/LS */
Alexander Mezin3f5dc082014-06-04 02:01:22 +07001299 .callback = battery_bix_broken_package_quirk,
Lan Tianyua90b4032014-01-06 22:50:37 +08001300 .matches = {
1301 DMI_MATCH(DMI_SYS_VENDOR, "NEC"),
1302 DMI_MATCH(DMI_PRODUCT_NAME, "PC-LZ750LS"),
1303 },
1304 },
Alexander Mezinf43691c2014-06-04 02:01:23 +07001305 {
Hans de Goede91afa072018-04-12 12:01:58 +02001306 /* Acer Aspire V5-573G */
Alexander Mezinf43691c2014-06-04 02:01:23 +07001307 .callback = battery_notification_delay_quirk,
Alexander Mezinf43691c2014-06-04 02:01:23 +07001308 .matches = {
1309 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
1310 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-573G"),
1311 },
1312 },
Hans de Goede1b799c52018-04-12 12:02:00 +02001313 {
1314 /* Point of View mobii wintab p800w */
1315 .callback = battery_ac_is_broken_quirk,
1316 .matches = {
1317 DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
1318 DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
1319 DMI_MATCH(DMI_BIOS_VERSION, "3BAIR1013"),
1320 /* Above matches are too generic, add bios-date match */
1321 DMI_MATCH(DMI_BIOS_DATE, "08/22/2014"),
1322 },
1323 },
Carlo Caioneec625a32018-04-18 14:04:39 +02001324 {
1325 /* ECS EF20EA */
1326 .callback = battery_do_not_check_pmic_quirk,
1327 .matches = {
1328 DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"),
1329 },
1330 },
1331 {
1332 /* Lenovo Ideapad Miix 320 */
1333 .callback = battery_do_not_check_pmic_quirk,
1334 .matches = {
1335 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
1336 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80XF"),
1337 DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
1338 },
1339 },
Lan Tianyua90b4032014-01-06 22:50:37 +08001340 {},
1341};
1342
Lan Tianyu75646e72014-07-07 15:47:12 +08001343/*
1344 * Some machines'(E,G Lenovo Z480) ECs are not stable
1345 * during boot up and this causes battery driver fails to be
1346 * probed due to failure of getting battery information
1347 * from EC sometimes. After several retries, the operation
1348 * may work. So add retry code here and 20ms sleep between
1349 * every retries.
1350 */
1351static int acpi_battery_update_retry(struct acpi_battery *battery)
1352{
1353 int retry, ret;
1354
1355 for (retry = 5; retry; retry--) {
1356 ret = acpi_battery_update(battery, false);
1357 if (!ret)
1358 break;
1359
1360 msleep(20);
1361 }
1362 return ret;
1363}
1364
Len Brown4be44fc2005-08-05 00:44:28 -04001365static int acpi_battery_add(struct acpi_device *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366{
Len Brown4be44fc2005-08-05 00:44:28 -04001367 int result = 0;
Len Brown4be44fc2005-08-05 00:44:28 -04001368 struct acpi_battery *battery = NULL;
Jiang Liu952c63e2013-06-29 00:24:38 +08001369
Linus Torvalds1da177e2005-04-16 15:20:36 -07001370 if (!device)
Patrick Mocheld550d982006-06-27 00:41:40 -04001371 return -EINVAL;
Lan Tianyu40e7fcb2014-11-23 21:22:54 +08001372
1373 if (device->dep_unmet)
1374 return -EPROBE_DEFER;
1375
Burman Yan36bcbec2006-12-19 12:56:11 -08001376 battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377 if (!battery)
Patrick Mocheld550d982006-06-27 00:41:40 -04001378 return -ENOMEM;
Patrick Mochel145def82006-05-19 16:54:39 -04001379 battery->device = device;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
1381 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
Pavel Machekdb89b4f2008-09-22 14:37:34 -07001382 device->driver_data = battery;
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +04001383 mutex_init(&battery->lock);
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +03001384 mutex_init(&battery->sysfs_lock);
Jiang Liu952c63e2013-06-29 00:24:38 +08001385 if (acpi_has_method(battery->device->handle, "_BIX"))
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +04001386 set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
Lan Tianyu75646e72014-07-07 15:47:12 +08001387
1388 result = acpi_battery_update_retry(battery);
Stefan Hajnoczieb03cb02011-07-12 09:03:29 +01001389 if (result)
1390 goto fail;
Lan Tianyu75646e72014-07-07 15:47:12 +08001391
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001392#ifdef CONFIG_ACPI_PROCFS_POWER
1393 result = acpi_battery_add_fs(device);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001394 if (result) {
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001395 acpi_battery_remove_fs(device);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001396 goto fail;
1397 }
Bjørn Mork6993ce42017-12-05 18:46:39 +01001398#endif
Kyle McMartin25be5822011-03-22 16:19:50 -04001399
Stefan Hajnoczie80bba42011-07-12 09:03:28 +01001400 printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
1401 ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
1402 device->status.battery_present ? "present" : "absent");
1403
Kyle McMartin25be5822011-03-22 16:19:50 -04001404 battery->pm_nb.notifier_call = battery_notify;
1405 register_pm_notifier(&battery->pm_nb);
1406
Zhang Ruie0d1f092014-05-28 15:23:38 +08001407 device_init_wakeup(&device->dev, 1);
1408
Patrick Mocheld550d982006-06-27 00:41:40 -04001409 return result;
Stefan Hajnoczie80bba42011-07-12 09:03:28 +01001410
1411fail:
1412 sysfs_remove_battery(battery);
1413 mutex_destroy(&battery->lock);
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +03001414 mutex_destroy(&battery->sysfs_lock);
Stefan Hajnoczie80bba42011-07-12 09:03:28 +01001415 kfree(battery);
1416 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001417}
1418
Rafael J. Wysocki51fac832013-01-24 00:24:48 +01001419static int acpi_battery_remove(struct acpi_device *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420{
Len Brown4be44fc2005-08-05 00:44:28 -04001421 struct acpi_battery *battery = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001422
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423 if (!device || !acpi_driver_data(device))
Patrick Mocheld550d982006-06-27 00:41:40 -04001424 return -EINVAL;
Zhang Ruie0d1f092014-05-28 15:23:38 +08001425 device_init_wakeup(&device->dev, 0);
Jan Engelhardt50dd0962006-10-01 00:28:50 +02001426 battery = acpi_driver_data(device);
Kyle McMartin25be5822011-03-22 16:19:50 -04001427 unregister_pm_notifier(&battery->pm_nb);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001428#ifdef CONFIG_ACPI_PROCFS_POWER
1429 acpi_battery_remove_fs(device);
1430#endif
Andrey Borzenkov508df922007-10-28 12:50:09 +03001431 sysfs_remove_battery(battery);
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +04001432 mutex_destroy(&battery->lock);
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +03001433 mutex_destroy(&battery->sysfs_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434 kfree(battery);
Patrick Mocheld550d982006-06-27 00:41:40 -04001435 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436}
1437
Rafael J. Wysocki90692402012-08-09 23:00:02 +02001438#ifdef CONFIG_PM_SLEEP
Jiri Kosina34c44152006-10-10 14:20:41 -07001439/* this is needed to learn about changes made in suspended state */
Rafael J. Wysockia6f50dc2012-06-27 23:26:43 +02001440static int acpi_battery_resume(struct device *dev)
Jiri Kosina34c44152006-10-10 14:20:41 -07001441{
1442 struct acpi_battery *battery;
Rafael J. Wysockia6f50dc2012-06-27 23:26:43 +02001443
1444 if (!dev)
Jiri Kosina34c44152006-10-10 14:20:41 -07001445 return -EINVAL;
Rafael J. Wysockia6f50dc2012-06-27 23:26:43 +02001446
1447 battery = acpi_driver_data(to_acpi_device(dev));
1448 if (!battery)
1449 return -EINVAL;
1450
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +04001451 battery->update_time = 0;
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001452 acpi_battery_update(battery, true);
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +03001453 return 0;
Jiri Kosina34c44152006-10-10 14:20:41 -07001454}
Shuah Khan7f6895c2014-02-12 20:19:06 -07001455#else
1456#define acpi_battery_resume NULL
Rafael J. Wysocki90692402012-08-09 23:00:02 +02001457#endif
Jiri Kosina34c44152006-10-10 14:20:41 -07001458
Rafael J. Wysockia6f50dc2012-06-27 23:26:43 +02001459static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume);
1460
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +04001461static struct acpi_driver acpi_battery_driver = {
1462 .name = "battery",
1463 .class = ACPI_BATTERY_CLASS,
1464 .ids = battery_device_ids,
Bjorn Helgaasd9406692009-04-30 09:35:47 -06001465 .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +04001466 .ops = {
1467 .add = acpi_battery_add,
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +04001468 .remove = acpi_battery_remove,
Bjorn Helgaasd9406692009-04-30 09:35:47 -06001469 .notify = acpi_battery_notify,
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +04001470 },
Rafael J. Wysockia6f50dc2012-06-27 23:26:43 +02001471 .drv.pm = &acpi_battery_pm,
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +04001472};
1473
Linus Torvaldsb0cbc862009-04-11 12:45:20 -07001474static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475{
Hans de Goededccfae62017-04-19 14:02:10 +02001476 unsigned int i;
Luis Henriques479faaf2015-05-11 22:48:46 +01001477 int result;
1478
Alexander Mezin3f5dc082014-06-04 02:01:22 +07001479 dmi_check_system(bat_dmi_table);
Luis Henriques479faaf2015-05-11 22:48:46 +01001480
Carlo Caioneec625a32018-04-18 14:04:39 +02001481 if (battery_check_pmic) {
1482 for (i = 0; i < ARRAY_SIZE(acpi_battery_blacklist); i++)
1483 if (acpi_dev_present(acpi_battery_blacklist[i], "1", -1)) {
1484 pr_info(PREFIX ACPI_BATTERY_DEVICE_NAME
1485 ": found native %s PMIC, not loading\n",
1486 acpi_battery_blacklist[i]);
1487 return;
1488 }
1489 }
1490
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001491#ifdef CONFIG_ACPI_PROCFS_POWER
1492 acpi_battery_dir = acpi_lock_battery_dir();
1493 if (!acpi_battery_dir)
1494 return;
1495#endif
Luis Henriques479faaf2015-05-11 22:48:46 +01001496 result = acpi_bus_register_driver(&acpi_battery_driver);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001497#ifdef CONFIG_ACPI_PROCFS_POWER
Luis Henriques479faaf2015-05-11 22:48:46 +01001498 if (result < 0)
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001499 acpi_unlock_battery_dir(acpi_battery_dir);
1500#endif
Hans de Goedebc39fbc2017-04-19 14:02:09 +02001501 battery_driver_registered = (result == 0);
Arjan van de Ven0f66af52009-01-10 14:19:05 -05001502}
1503
1504static int __init acpi_battery_init(void)
1505{
Luis Henriquese234b072015-05-11 22:48:38 +01001506 if (acpi_disabled)
1507 return -ENODEV;
1508
Luis Henriqueseca21d912015-05-11 22:49:05 +01001509 async_cookie = async_schedule(acpi_battery_init_async, NULL);
Patrick Mocheld550d982006-06-27 00:41:40 -04001510 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511}
1512
Len Brown4be44fc2005-08-05 00:44:28 -04001513static void __exit acpi_battery_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001514{
Chris Wilson5dfa0c72016-05-19 09:11:52 +01001515 async_synchronize_cookie(async_cookie + 1);
Ognjen Galicfa938542018-02-07 15:58:13 +01001516 if (battery_driver_registered) {
Hans de Goedebc39fbc2017-04-19 14:02:09 +02001517 acpi_bus_unregister_driver(&acpi_battery_driver);
Ognjen Galicfa938542018-02-07 15:58:13 +01001518 battery_hook_exit();
1519 }
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001520#ifdef CONFIG_ACPI_PROCFS_POWER
Hans de Goedebc39fbc2017-04-19 14:02:09 +02001521 if (acpi_battery_dir)
1522 acpi_unlock_battery_dir(acpi_battery_dir);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001523#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524}
1525
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526module_init(acpi_battery_init);
1527module_exit(acpi_battery_exit);