blob: 572845fafb007edcc5f650e08ad2a6d776e88c58 [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);
86
87enum acpi_battery_files {
88 info_tag = 0,
89 state_tag,
90 alarm_tag,
91 ACPI_BATTERY_NUMFILES,
92};
93
94#endif
95
Alexey Starikovskiyd7380962007-09-26 19:43:04 +040096static const struct acpi_device_id battery_device_ids[] = {
97 {"PNP0C0A", 0},
98 {"", 0},
99};
100
101MODULE_DEVICE_TABLE(acpi, battery_device_ids);
102
Hans de Goededccfae62017-04-19 14:02:10 +0200103/* Lists of PMIC ACPI HIDs with an (often better) native battery driver */
104static const char * const acpi_battery_blacklist[] = {
105 "INT33F4", /* X-Powers AXP288 PMIC */
106};
107
Alexey Starikovskiy7b3bcc42009-10-15 14:31:24 +0400108enum {
109 ACPI_BATTERY_ALARM_PRESENT,
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400110 ACPI_BATTERY_XINFO_PRESENT,
Zhang Rui557d5862010-10-22 10:02:06 +0800111 ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
Kamil Iskra4000e622012-11-16 22:28:58 +0100112 /* On Lenovo Thinkpad models from 2010 and 2011, the power unit
113 switches between mWh and mAh depending on whether the system
114 is running on battery or not. When mAh is the unit, most
115 reported values are incorrect and need to be adjusted by
116 10000/design_voltage. Verified on x201, t410, t410s, and x220.
117 Pre-2010 and 2012 models appear to always report in mWh and
118 are thus unaffected (tested with t42, t61, t500, x200, x300,
119 and x230). Also, in mid-2012 Lenovo issued a BIOS update for
120 the 2011 models that fixes the issue (tested on x220 with a
121 post-1.29 BIOS), but as of Nov. 2012, no such update is
122 available for the 2010 models. */
123 ACPI_BATTERY_QUIRK_THINKPAD_MAH,
Laszlo Totha20136a2018-02-24 10:20:15 +0100124 /* for batteries reporting current capacity with design capacity
125 * on a full charge, but showing degradation in full charge cap.
126 */
127 ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE,
Alexey Starikovskiy7b3bcc42009-10-15 14:31:24 +0400128};
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400129
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400130struct acpi_battery {
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400131 struct mutex lock;
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +0300132 struct mutex sysfs_lock;
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100133 struct power_supply *bat;
134 struct power_supply_desc bat_desc;
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400135 struct acpi_device *device;
Kyle McMartin25be5822011-03-22 16:19:50 -0400136 struct notifier_block pm_nb;
Ognjen Galicfa938542018-02-07 15:58:13 +0100137 struct list_head list;
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400138 unsigned long update_time;
Lan Tianyu016d5ba2013-07-30 14:00:42 +0200139 int revision;
Alexey Starikovskiy7faa1442009-03-27 22:23:52 -0400140 int rate_now;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400141 int capacity_now;
142 int voltage_now;
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400143 int design_capacity;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400144 int full_charge_capacity;
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400145 int technology;
146 int design_voltage;
147 int design_capacity_warning;
148 int design_capacity_low;
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400149 int cycle_count;
150 int measurement_accuracy;
151 int max_sampling_time;
152 int min_sampling_time;
153 int max_averaging_interval;
154 int min_averaging_interval;
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400155 int capacity_granularity_1;
156 int capacity_granularity_2;
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400157 int alarm;
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400158 char model_number[32];
159 char serial_number[32];
160 char type[32];
161 char oem_info[32];
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400162 int state;
163 int power_unit;
Alexey Starikovskiy7b3bcc42009-10-15 14:31:24 +0400164 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165};
166
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100167#define to_acpi_battery(x) power_supply_get_drvdata(x)
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400168
Andy Shevchenkoefd941f2013-03-11 09:17:06 +0000169static inline int acpi_battery_present(struct acpi_battery *battery)
Alexey Starikovskiy78490d82007-05-11 13:18:55 -0400170{
171 return battery->device->status.battery_present;
172}
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400173
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400174static int acpi_battery_technology(struct acpi_battery *battery)
175{
176 if (!strcasecmp("NiCd", battery->type))
177 return POWER_SUPPLY_TECHNOLOGY_NiCd;
178 if (!strcasecmp("NiMH", battery->type))
179 return POWER_SUPPLY_TECHNOLOGY_NiMH;
180 if (!strcasecmp("LION", battery->type))
181 return POWER_SUPPLY_TECHNOLOGY_LION;
Andrey Borzenkovad40e682007-11-10 20:02:49 +0300182 if (!strncasecmp("LI-ION", battery->type, 6))
Alexey Starikovskiy0bde7ee2007-10-28 15:33:10 +0300183 return POWER_SUPPLY_TECHNOLOGY_LION;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400184 if (!strcasecmp("LiP", battery->type))
185 return POWER_SUPPLY_TECHNOLOGY_LIPO;
186 return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
187}
188
Alexey Starikovskiy91044762007-11-13 12:23:06 +0300189static int acpi_battery_get_state(struct acpi_battery *battery);
Alexey Starikovskiyb19073a2007-10-25 17:10:47 -0400190
Richard Hughes56f382a2009-01-25 15:05:50 +0000191static int acpi_battery_is_charged(struct acpi_battery *battery)
192{
Zhang Rui1ac5aaa2014-05-28 15:23:36 +0800193 /* charging, discharging or critical low */
Richard Hughes56f382a2009-01-25 15:05:50 +0000194 if (battery->state != 0)
195 return 0;
196
197 /* battery not reporting charge */
198 if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN ||
199 battery->capacity_now == 0)
200 return 0;
201
202 /* good batteries update full_charge as the batteries degrade */
203 if (battery->full_charge_capacity == battery->capacity_now)
204 return 1;
205
206 /* fallback to using design values for broken batteries */
207 if (battery->design_capacity == battery->capacity_now)
208 return 1;
209
210 /* we don't do any sort of metric based on percentages */
211 return 0;
212}
213
Laszlo Totha20136a2018-02-24 10:20:15 +0100214static bool acpi_battery_is_degraded(struct acpi_battery *battery)
215{
216 return battery->full_charge_capacity && battery->design_capacity &&
217 battery->full_charge_capacity < battery->design_capacity;
218}
219
Hans de Goede19fffc82018-04-12 12:01:59 +0200220static int acpi_battery_handle_discharging(struct acpi_battery *battery)
221{
222 /*
223 * Some devices wrongly report discharging if the battery's charge level
224 * was above the device's start charging threshold atm the AC adapter
225 * was plugged in and the device thus did not start a new charge cycle.
226 */
Hans de Goede1b799c52018-04-12 12:02:00 +0200227 if ((battery_ac_is_broken || power_supply_is_system_supplied()) &&
228 battery->rate_now == 0)
Hans de Goede19fffc82018-04-12 12:01:59 +0200229 return POWER_SUPPLY_STATUS_NOT_CHARGING;
230
231 return POWER_SUPPLY_STATUS_DISCHARGING;
232}
233
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400234static int acpi_battery_get_property(struct power_supply *psy,
235 enum power_supply_property psp,
236 union power_supply_propval *val)
237{
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200238 int ret = 0;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400239 struct acpi_battery *battery = to_acpi_battery(psy);
240
Alexey Starikovskiy91044762007-11-13 12:23:06 +0300241 if (acpi_battery_present(battery)) {
242 /* run battery update only if it is present */
243 acpi_battery_get_state(battery);
244 } else if (psp != POWER_SUPPLY_PROP_PRESENT)
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400245 return -ENODEV;
246 switch (psp) {
247 case POWER_SUPPLY_PROP_STATUS:
Daniel Drake82bf43b2018-03-14 16:42:17 +0800248 if (battery->state & ACPI_BATTERY_STATE_DISCHARGING)
Hans de Goede19fffc82018-04-12 12:01:59 +0200249 val->intval = acpi_battery_handle_discharging(battery);
Daniel Drake82bf43b2018-03-14 16:42:17 +0800250 else if (battery->state & ACPI_BATTERY_STATE_CHARGING)
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400251 val->intval = POWER_SUPPLY_STATUS_CHARGING;
Richard Hughes56f382a2009-01-25 15:05:50 +0000252 else if (acpi_battery_is_charged(battery))
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400253 val->intval = POWER_SUPPLY_STATUS_FULL;
Roland Dreier4c41d3a2007-11-07 15:09:09 -0800254 else
255 val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400256 break;
257 case POWER_SUPPLY_PROP_PRESENT:
258 val->intval = acpi_battery_present(battery);
259 break;
260 case POWER_SUPPLY_PROP_TECHNOLOGY:
261 val->intval = acpi_battery_technology(battery);
262 break;
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400263 case POWER_SUPPLY_PROP_CYCLE_COUNT:
264 val->intval = battery->cycle_count;
265 break;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400266 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200267 if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
268 ret = -ENODEV;
269 else
270 val->intval = battery->design_voltage * 1000;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400271 break;
272 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200273 if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
274 ret = -ENODEV;
275 else
276 val->intval = battery->voltage_now * 1000;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400277 break;
278 case POWER_SUPPLY_PROP_CURRENT_NOW:
Alexey Starikovskiy7faa1442009-03-27 22:23:52 -0400279 case POWER_SUPPLY_PROP_POWER_NOW:
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200280 if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
281 ret = -ENODEV;
282 else
283 val->intval = battery->rate_now * 1000;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400284 break;
285 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
286 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200287 if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
288 ret = -ENODEV;
289 else
290 val->intval = battery->design_capacity * 1000;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400291 break;
292 case POWER_SUPPLY_PROP_CHARGE_FULL:
293 case POWER_SUPPLY_PROP_ENERGY_FULL:
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200294 if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
295 ret = -ENODEV;
296 else
297 val->intval = battery->full_charge_capacity * 1000;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400298 break;
299 case POWER_SUPPLY_PROP_CHARGE_NOW:
300 case POWER_SUPPLY_PROP_ENERGY_NOW:
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200301 if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
302 ret = -ENODEV;
303 else
304 val->intval = battery->capacity_now * 1000;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400305 break;
srinivas pandruvadaa58e1152012-04-05 17:38:54 -0700306 case POWER_SUPPLY_PROP_CAPACITY:
307 if (battery->capacity_now && battery->full_charge_capacity)
308 val->intval = battery->capacity_now * 100/
309 battery->full_charge_capacity;
310 else
311 val->intval = 0;
312 break;
Zhang Rui1ac5aaa2014-05-28 15:23:36 +0800313 case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
314 if (battery->state & ACPI_BATTERY_STATE_CRITICAL)
315 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
316 else if (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) &&
317 (battery->capacity_now <= battery->alarm))
318 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
319 else if (acpi_battery_is_charged(battery))
320 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
321 else
322 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
323 break;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400324 case POWER_SUPPLY_PROP_MODEL_NAME:
325 val->strval = battery->model_number;
326 break;
327 case POWER_SUPPLY_PROP_MANUFACTURER:
328 val->strval = battery->oem_info;
329 break;
maximilian attems7c2670b2008-01-22 18:46:50 +0100330 case POWER_SUPPLY_PROP_SERIAL_NUMBER:
331 val->strval = battery->serial_number;
332 break;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400333 default:
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200334 ret = -EINVAL;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400335 }
Rafael J. Wysockia1b4bd62010-10-23 19:35:15 +0200336 return ret;
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400337}
338
339static enum power_supply_property charge_battery_props[] = {
340 POWER_SUPPLY_PROP_STATUS,
341 POWER_SUPPLY_PROP_PRESENT,
342 POWER_SUPPLY_PROP_TECHNOLOGY,
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400343 POWER_SUPPLY_PROP_CYCLE_COUNT,
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400344 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
345 POWER_SUPPLY_PROP_VOLTAGE_NOW,
346 POWER_SUPPLY_PROP_CURRENT_NOW,
347 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
348 POWER_SUPPLY_PROP_CHARGE_FULL,
349 POWER_SUPPLY_PROP_CHARGE_NOW,
srinivas pandruvadaa58e1152012-04-05 17:38:54 -0700350 POWER_SUPPLY_PROP_CAPACITY,
Zhang Rui1ac5aaa2014-05-28 15:23:36 +0800351 POWER_SUPPLY_PROP_CAPACITY_LEVEL,
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400352 POWER_SUPPLY_PROP_MODEL_NAME,
353 POWER_SUPPLY_PROP_MANUFACTURER,
maximilian attems7c2670b2008-01-22 18:46:50 +0100354 POWER_SUPPLY_PROP_SERIAL_NUMBER,
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400355};
356
357static enum power_supply_property energy_battery_props[] = {
358 POWER_SUPPLY_PROP_STATUS,
359 POWER_SUPPLY_PROP_PRESENT,
360 POWER_SUPPLY_PROP_TECHNOLOGY,
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400361 POWER_SUPPLY_PROP_CYCLE_COUNT,
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400362 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
363 POWER_SUPPLY_PROP_VOLTAGE_NOW,
Alexey Starikovskiy7faa1442009-03-27 22:23:52 -0400364 POWER_SUPPLY_PROP_POWER_NOW,
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400365 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
366 POWER_SUPPLY_PROP_ENERGY_FULL,
367 POWER_SUPPLY_PROP_ENERGY_NOW,
srinivas pandruvadaa58e1152012-04-05 17:38:54 -0700368 POWER_SUPPLY_PROP_CAPACITY,
Zhang Rui1ac5aaa2014-05-28 15:23:36 +0800369 POWER_SUPPLY_PROP_CAPACITY_LEVEL,
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400370 POWER_SUPPLY_PROP_MODEL_NAME,
371 POWER_SUPPLY_PROP_MANUFACTURER,
maximilian attems7c2670b2008-01-22 18:46:50 +0100372 POWER_SUPPLY_PROP_SERIAL_NUMBER,
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400373};
374
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375/* --------------------------------------------------------------------------
376 Battery Management
377 -------------------------------------------------------------------------- */
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400378struct acpi_offsets {
379 size_t offset; /* offset inside struct acpi_sbs_battery */
380 u8 mode; /* int or string? */
381};
382
Mathias Krausea4658782015-06-13 14:26:53 +0200383static const struct acpi_offsets state_offsets[] = {
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400384 {offsetof(struct acpi_battery, state), 0},
Alexey Starikovskiy7faa1442009-03-27 22:23:52 -0400385 {offsetof(struct acpi_battery, rate_now), 0},
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400386 {offsetof(struct acpi_battery, capacity_now), 0},
387 {offsetof(struct acpi_battery, voltage_now), 0},
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400388};
389
Mathias Krausea4658782015-06-13 14:26:53 +0200390static const struct acpi_offsets info_offsets[] = {
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400391 {offsetof(struct acpi_battery, power_unit), 0},
392 {offsetof(struct acpi_battery, design_capacity), 0},
Alexey Starikovskiyd7380962007-09-26 19:43:04 +0400393 {offsetof(struct acpi_battery, full_charge_capacity), 0},
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400394 {offsetof(struct acpi_battery, technology), 0},
395 {offsetof(struct acpi_battery, design_voltage), 0},
396 {offsetof(struct acpi_battery, design_capacity_warning), 0},
397 {offsetof(struct acpi_battery, design_capacity_low), 0},
398 {offsetof(struct acpi_battery, capacity_granularity_1), 0},
399 {offsetof(struct acpi_battery, capacity_granularity_2), 0},
400 {offsetof(struct acpi_battery, model_number), 1},
401 {offsetof(struct acpi_battery, serial_number), 1},
402 {offsetof(struct acpi_battery, type), 1},
403 {offsetof(struct acpi_battery, oem_info), 1},
404};
405
Mathias Krausea4658782015-06-13 14:26:53 +0200406static const struct acpi_offsets extended_info_offsets[] = {
Lan Tianyu016d5ba2013-07-30 14:00:42 +0200407 {offsetof(struct acpi_battery, revision), 0},
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400408 {offsetof(struct acpi_battery, power_unit), 0},
409 {offsetof(struct acpi_battery, design_capacity), 0},
410 {offsetof(struct acpi_battery, full_charge_capacity), 0},
411 {offsetof(struct acpi_battery, technology), 0},
412 {offsetof(struct acpi_battery, design_voltage), 0},
413 {offsetof(struct acpi_battery, design_capacity_warning), 0},
414 {offsetof(struct acpi_battery, design_capacity_low), 0},
415 {offsetof(struct acpi_battery, cycle_count), 0},
416 {offsetof(struct acpi_battery, measurement_accuracy), 0},
417 {offsetof(struct acpi_battery, max_sampling_time), 0},
418 {offsetof(struct acpi_battery, min_sampling_time), 0},
419 {offsetof(struct acpi_battery, max_averaging_interval), 0},
420 {offsetof(struct acpi_battery, min_averaging_interval), 0},
421 {offsetof(struct acpi_battery, capacity_granularity_1), 0},
422 {offsetof(struct acpi_battery, capacity_granularity_2), 0},
423 {offsetof(struct acpi_battery, model_number), 1},
424 {offsetof(struct acpi_battery, serial_number), 1},
425 {offsetof(struct acpi_battery, type), 1},
426 {offsetof(struct acpi_battery, oem_info), 1},
427};
428
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400429static int extract_package(struct acpi_battery *battery,
430 union acpi_object *package,
Mathias Krausea4658782015-06-13 14:26:53 +0200431 const struct acpi_offsets *offsets, int num)
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300432{
Alexey Starikovskiy106449e2007-10-29 23:29:40 +0300433 int i;
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400434 union acpi_object *element;
435 if (package->type != ACPI_TYPE_PACKAGE)
436 return -EFAULT;
437 for (i = 0; i < num; ++i) {
438 if (package->package.count <= i)
439 return -EFAULT;
440 element = &package->package.elements[i];
441 if (offsets[i].mode) {
Alexey Starikovskiy106449e2007-10-29 23:29:40 +0300442 u8 *ptr = (u8 *)battery + offsets[i].offset;
443 if (element->type == ACPI_TYPE_STRING ||
444 element->type == ACPI_TYPE_BUFFER)
445 strncpy(ptr, element->string.pointer, 32);
446 else if (element->type == ACPI_TYPE_INTEGER) {
447 strncpy(ptr, (u8 *)&element->integer.value,
Lin Ming439913f2010-01-28 10:53:19 +0800448 sizeof(u64));
449 ptr[sizeof(u64)] = 0;
Alexey Starikovskiyb8a1bdb2008-03-17 22:37:42 -0400450 } else
451 *ptr = 0; /* don't have value */
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400452 } else {
Alexey Starikovskiyb8a1bdb2008-03-17 22:37:42 -0400453 int *x = (int *)((u8 *)battery + offsets[i].offset);
454 *x = (element->type == ACPI_TYPE_INTEGER) ?
455 element->integer.value : -1;
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300456 }
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300457 }
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300458 return 0;
459}
460
461static int acpi_battery_get_status(struct acpi_battery *battery)
462{
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400463 if (acpi_bus_get_status(battery->device)) {
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300464 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA"));
465 return -ENODEV;
466 }
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400467 return 0;
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300468}
469
Dave Lambley2d09af42016-11-04 01:05:40 +0000470
471static int extract_battery_info(const int use_bix,
472 struct acpi_battery *battery,
473 const struct acpi_buffer *buffer)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474{
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400475 int result = -EFAULT;
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400476
Dave Lambley2d09af42016-11-04 01:05:40 +0000477 if (use_bix && battery_bix_broken_package)
478 result = extract_package(battery, buffer->pointer,
Lan Tianyua90b4032014-01-06 22:50:37 +0800479 extended_info_offsets + 1,
480 ARRAY_SIZE(extended_info_offsets) - 1);
Dave Lambley2d09af42016-11-04 01:05:40 +0000481 else if (use_bix)
482 result = extract_package(battery, buffer->pointer,
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400483 extended_info_offsets,
484 ARRAY_SIZE(extended_info_offsets));
485 else
Dave Lambley2d09af42016-11-04 01:05:40 +0000486 result = extract_package(battery, buffer->pointer,
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400487 info_offsets, ARRAY_SIZE(info_offsets));
Zhang Rui557d5862010-10-22 10:02:06 +0800488 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
489 battery->full_charge_capacity = battery->design_capacity;
Kamil Iskra4000e622012-11-16 22:28:58 +0100490 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) &&
491 battery->power_unit && battery->design_voltage) {
492 battery->design_capacity = battery->design_capacity *
493 10000 / battery->design_voltage;
494 battery->full_charge_capacity = battery->full_charge_capacity *
495 10000 / battery->design_voltage;
496 battery->design_capacity_warning =
497 battery->design_capacity_warning *
498 10000 / battery->design_voltage;
499 /* Curiously, design_capacity_low, unlike the rest of them,
500 is correct. */
501 /* capacity_granularity_* equal 1 on the systems tested, so
502 it's impossible to tell if they would need an adjustment
503 or not if their values were higher. */
504 }
Laszlo Totha20136a2018-02-24 10:20:15 +0100505 if (test_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags) &&
506 battery->capacity_now > battery->full_charge_capacity)
507 battery->capacity_now = battery->full_charge_capacity;
508
Patrick Mocheld550d982006-06-27 00:41:40 -0400509 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510}
511
Dave Lambley2d09af42016-11-04 01:05:40 +0000512static int acpi_battery_get_info(struct acpi_battery *battery)
513{
514 const int xinfo = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
515 int use_bix;
516 int result = -ENODEV;
517
518 if (!acpi_battery_present(battery))
519 return 0;
520
521
522 for (use_bix = xinfo ? 1 : 0; use_bix >= 0; use_bix--) {
523 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
524 acpi_status status = AE_ERROR;
525
526 mutex_lock(&battery->lock);
527 status = acpi_evaluate_object(battery->device->handle,
528 use_bix ? "_BIX":"_BIF",
529 NULL, &buffer);
530 mutex_unlock(&battery->lock);
531
532 if (ACPI_FAILURE(status)) {
533 ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s",
534 use_bix ? "_BIX":"_BIF"));
535 } else {
536 result = extract_battery_info(use_bix,
537 battery,
538 &buffer);
539
540 kfree(buffer.pointer);
541 break;
542 }
543 }
544
545 if (!result && !use_bix && xinfo)
546 pr_warn(FW_BUG "The _BIX method is broken, using _BIF.\n");
547
548 return result;
549}
550
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300551static int acpi_battery_get_state(struct acpi_battery *battery)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552{
Len Brown4be44fc2005-08-05 00:44:28 -0400553 int result = 0;
554 acpi_status status = 0;
555 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300557 if (!acpi_battery_present(battery))
558 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400560 if (battery->update_time &&
561 time_before(jiffies, battery->update_time +
562 msecs_to_jiffies(cache_time)))
563 return 0;
564
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400565 mutex_lock(&battery->lock);
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400566 status = acpi_evaluate_object(battery->device->handle, "_BST",
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400567 NULL, &buffer);
568 mutex_unlock(&battery->lock);
Len Brown5b31d892007-08-15 00:19:26 -0400569
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570 if (ACPI_FAILURE(status)) {
Thomas Renningera6fc6722006-06-26 23:58:43 -0400571 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
Patrick Mocheld550d982006-06-27 00:41:40 -0400572 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573 }
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400574
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400575 result = extract_package(battery, buffer.pointer,
576 state_offsets, ARRAY_SIZE(state_offsets));
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400577 battery->update_time = jiffies;
Alexey Starikovskiy78490d82007-05-11 13:18:55 -0400578 kfree(buffer.pointer);
Hector Martinbc76f902009-08-06 15:57:48 -0700579
Lan Tianyu55003b22011-06-30 11:33:12 +0800580 /* For buggy DSDTs that report negative 16-bit values for either
581 * charging or discharging current and/or report 0 as 65536
582 * due to bad math.
583 */
584 if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA &&
585 battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN &&
586 (s16)(battery->rate_now) < 0) {
Hector Martinbc76f902009-08-06 15:57:48 -0700587 battery->rate_now = abs((s16)battery->rate_now);
Martin Kepplinger92375162015-03-13 00:48:17 +0100588 printk_once(KERN_WARNING FW_BUG
589 "battery: (dis)charge rate invalid.\n");
Lan Tianyu55003b22011-06-30 11:33:12 +0800590 }
Hector Martinbc76f902009-08-06 15:57:48 -0700591
Zhang Rui557d5862010-10-22 10:02:06 +0800592 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
593 && battery->capacity_now >= 0 && battery->capacity_now <= 100)
594 battery->capacity_now = (battery->capacity_now *
595 battery->full_charge_capacity) / 100;
Kamil Iskra4000e622012-11-16 22:28:58 +0100596 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) &&
597 battery->power_unit && battery->design_voltage) {
598 battery->capacity_now = battery->capacity_now *
599 10000 / battery->design_voltage;
600 }
Laszlo Totha20136a2018-02-24 10:20:15 +0100601 if (test_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags) &&
602 battery->capacity_now > battery->full_charge_capacity)
603 battery->capacity_now = battery->full_charge_capacity;
604
Patrick Mocheld550d982006-06-27 00:41:40 -0400605 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606}
607
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400608static int acpi_battery_set_alarm(struct acpi_battery *battery)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609{
Len Brown4be44fc2005-08-05 00:44:28 -0400610 acpi_status status = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +0400612 if (!acpi_battery_present(battery) ||
Alexey Starikovskiy7b3bcc42009-10-15 14:31:24 +0400613 !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags))
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300614 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400616 mutex_lock(&battery->lock);
Jiang Liu0db98202013-06-29 00:24:39 +0800617 status = acpi_execute_simple_method(battery->device->handle, "_BTP",
618 battery->alarm);
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +0400619 mutex_unlock(&battery->lock);
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400620
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621 if (ACPI_FAILURE(status))
Patrick Mocheld550d982006-06-27 00:41:40 -0400622 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400624 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", battery->alarm));
Patrick Mocheld550d982006-06-27 00:41:40 -0400625 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626}
627
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300628static int acpi_battery_init_alarm(struct acpi_battery *battery)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629{
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300630 /* See if alarms are supported, and if so, set default */
Jiang Liu952c63e2013-06-29 00:24:38 +0800631 if (!acpi_has_method(battery->device->handle, "_BTP")) {
Alexey Starikovskiy7b3bcc42009-10-15 14:31:24 +0400632 clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400633 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634 }
Alexey Starikovskiy7b3bcc42009-10-15 14:31:24 +0400635 set_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags);
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +0400636 if (!battery->alarm)
637 battery->alarm = battery->design_capacity_warning;
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +0400638 return acpi_battery_set_alarm(battery);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639}
640
Andrey Borzenkov508df922007-10-28 12:50:09 +0300641static ssize_t acpi_battery_alarm_show(struct device *dev,
642 struct device_attribute *attr,
643 char *buf)
644{
645 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
646 return sprintf(buf, "%d\n", battery->alarm * 1000);
647}
648
649static ssize_t acpi_battery_alarm_store(struct device *dev,
650 struct device_attribute *attr,
651 const char *buf, size_t count)
652{
653 unsigned long x;
654 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
Luis G.F47a08c82014-01-21 15:40:43 +0100655 if (sscanf(buf, "%lu\n", &x) == 1)
Andrey Borzenkov508df922007-10-28 12:50:09 +0300656 battery->alarm = x/1000;
657 if (acpi_battery_present(battery))
658 acpi_battery_set_alarm(battery);
659 return count;
660}
661
Bhumika Goyal82d2b612017-08-21 17:13:07 +0530662static const struct device_attribute alarm_attr = {
Parag Warudkar01e8ef12008-10-18 20:28:50 -0700663 .attr = {.name = "alarm", .mode = 0644},
Andrey Borzenkov508df922007-10-28 12:50:09 +0300664 .show = acpi_battery_alarm_show,
665 .store = acpi_battery_alarm_store,
666};
667
Ognjen Galicfa938542018-02-07 15:58:13 +0100668/*
669 * The Battery Hooking API
670 *
671 * This API is used inside other drivers that need to expose
672 * platform-specific behaviour within the generic driver in a
673 * generic way.
674 *
675 */
676
677static LIST_HEAD(acpi_battery_list);
678static LIST_HEAD(battery_hook_list);
679static DEFINE_MUTEX(hook_mutex);
680
Colin Ian King514bcc52018-02-23 16:32:55 +0000681static void __battery_hook_unregister(struct acpi_battery_hook *hook, int lock)
Ognjen Galicfa938542018-02-07 15:58:13 +0100682{
683 struct acpi_battery *battery;
684 /*
685 * In order to remove a hook, we first need to
686 * de-register all the batteries that are registered.
687 */
688 if (lock)
689 mutex_lock(&hook_mutex);
690 list_for_each_entry(battery, &acpi_battery_list, list) {
691 hook->remove_battery(battery->bat);
692 }
693 list_del(&hook->list);
694 if (lock)
695 mutex_unlock(&hook_mutex);
696 pr_info("extension unregistered: %s\n", hook->name);
697}
698
699void battery_hook_unregister(struct acpi_battery_hook *hook)
700{
701 __battery_hook_unregister(hook, 1);
702}
703EXPORT_SYMBOL_GPL(battery_hook_unregister);
704
705void battery_hook_register(struct acpi_battery_hook *hook)
706{
707 struct acpi_battery *battery;
708
709 mutex_lock(&hook_mutex);
710 INIT_LIST_HEAD(&hook->list);
711 list_add(&hook->list, &battery_hook_list);
712 /*
713 * Now that the driver is registered, we need
714 * to notify the hook that a battery is available
715 * for each battery, so that the driver may add
716 * its attributes.
717 */
718 list_for_each_entry(battery, &acpi_battery_list, list) {
719 if (hook->add_battery(battery->bat)) {
720 /*
721 * If a add-battery returns non-zero,
722 * the registration of the extension has failed,
723 * and we will not add it to the list of loaded
724 * hooks.
725 */
726 pr_err("extension failed to load: %s", hook->name);
727 __battery_hook_unregister(hook, 0);
728 return;
729 }
730 }
731 pr_info("new extension: %s\n", hook->name);
732 mutex_unlock(&hook_mutex);
733}
734EXPORT_SYMBOL_GPL(battery_hook_register);
735
736/*
737 * This function gets called right after the battery sysfs
738 * attributes have been added, so that the drivers that
739 * define custom sysfs attributes can add their own.
Rafael J. Wysocki7a4ea102018-03-13 10:07:49 +0100740*/
Ognjen Galicfa938542018-02-07 15:58:13 +0100741static void battery_hook_add_battery(struct acpi_battery *battery)
742{
743 struct acpi_battery_hook *hook_node;
744
745 mutex_lock(&hook_mutex);
746 INIT_LIST_HEAD(&battery->list);
747 list_add(&battery->list, &acpi_battery_list);
748 /*
749 * Since we added a new battery to the list, we need to
750 * iterate over the hooks and call add_battery for each
751 * hook that was registered. This usually happens
752 * when a battery gets hotplugged or initialized
753 * during the battery module initialization.
754 */
755 list_for_each_entry(hook_node, &battery_hook_list, list) {
756 if (hook_node->add_battery(battery->bat)) {
757 /*
758 * The notification of the extensions has failed, to
759 * prevent further errors we will unload the extension.
760 */
761 __battery_hook_unregister(hook_node, 0);
762 pr_err("error in extension, unloading: %s",
763 hook_node->name);
764 }
765 }
766 mutex_unlock(&hook_mutex);
767}
768
769static void battery_hook_remove_battery(struct acpi_battery *battery)
770{
771 struct acpi_battery_hook *hook;
772
773 mutex_lock(&hook_mutex);
774 /*
775 * Before removing the hook, we need to remove all
776 * custom attributes from the battery.
777 */
778 list_for_each_entry(hook, &battery_hook_list, list) {
779 hook->remove_battery(battery->bat);
780 }
781 /* Then, just remove the battery from the list */
782 list_del(&battery->list);
783 mutex_unlock(&hook_mutex);
784}
785
786static void __exit battery_hook_exit(void)
787{
788 struct acpi_battery_hook *hook;
789 struct acpi_battery_hook *ptr;
790 /*
791 * At this point, the acpi_bus_unregister_driver()
792 * has called remove for all batteries. We just
793 * need to remove the hooks.
794 */
795 list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) {
796 __battery_hook_unregister(hook, 1);
797 }
798 mutex_destroy(&hook_mutex);
799}
800
Andrey Borzenkov508df922007-10-28 12:50:09 +0300801static int sysfs_add_battery(struct acpi_battery *battery)
802{
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100803 struct power_supply_config psy_cfg = { .drv_data = battery, };
Andrey Borzenkov508df922007-10-28 12:50:09 +0300804
Lan Tianyuae6f6182011-06-30 11:32:40 +0800805 if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) {
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100806 battery->bat_desc.properties = charge_battery_props;
807 battery->bat_desc.num_properties =
Andrey Borzenkov508df922007-10-28 12:50:09 +0300808 ARRAY_SIZE(charge_battery_props);
809 } else {
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100810 battery->bat_desc.properties = energy_battery_props;
811 battery->bat_desc.num_properties =
Andrey Borzenkov508df922007-10-28 12:50:09 +0300812 ARRAY_SIZE(energy_battery_props);
813 }
814
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100815 battery->bat_desc.name = acpi_device_bid(battery->device);
816 battery->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY;
817 battery->bat_desc.get_property = acpi_battery_get_property;
Andrey Borzenkov508df922007-10-28 12:50:09 +0300818
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100819 battery->bat = power_supply_register_no_ws(&battery->device->dev,
820 &battery->bat_desc, &psy_cfg);
Zhang Ruie0d1f092014-05-28 15:23:38 +0800821
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100822 if (IS_ERR(battery->bat)) {
823 int result = PTR_ERR(battery->bat);
824
825 battery->bat = NULL;
Andrey Borzenkov508df922007-10-28 12:50:09 +0300826 return result;
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100827 }
Ognjen Galicfa938542018-02-07 15:58:13 +0100828 battery_hook_add_battery(battery);
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100829 return device_create_file(&battery->bat->dev, &alarm_attr);
Andrey Borzenkov508df922007-10-28 12:50:09 +0300830}
831
832static void sysfs_remove_battery(struct acpi_battery *battery)
833{
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +0300834 mutex_lock(&battery->sysfs_lock);
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100835 if (!battery->bat) {
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +0300836 mutex_unlock(&battery->sysfs_lock);
Andrey Borzenkov508df922007-10-28 12:50:09 +0300837 return;
Lan Tianyu9c921c222011-06-30 11:34:12 +0800838 }
Ognjen Galicfa938542018-02-07 15:58:13 +0100839 battery_hook_remove_battery(battery);
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100840 device_remove_file(&battery->bat->dev, &alarm_attr);
841 power_supply_unregister(battery->bat);
842 battery->bat = NULL;
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +0300843 mutex_unlock(&battery->sysfs_lock);
Hector Martinbc76f902009-08-06 15:57:48 -0700844}
845
Kamil Iskra4000e622012-11-16 22:28:58 +0100846static void find_battery(const struct dmi_header *dm, void *private)
847{
848 struct acpi_battery *battery = (struct acpi_battery *)private;
849 /* Note: the hardcoded offsets below have been extracted from
850 the source code of dmidecode. */
851 if (dm->type == DMI_ENTRY_PORTABLE_BATTERY && dm->length >= 8) {
852 const u8 *dmi_data = (const u8 *)(dm + 1);
853 int dmi_capacity = get_unaligned((const u16 *)(dmi_data + 6));
854 if (dm->length >= 18)
855 dmi_capacity *= dmi_data[17];
856 if (battery->design_capacity * battery->design_voltage / 1000
857 != dmi_capacity &&
858 battery->design_capacity * 10 == dmi_capacity)
859 set_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH,
860 &battery->flags);
861 }
862}
863
Zhang Rui557d5862010-10-22 10:02:06 +0800864/*
865 * According to the ACPI spec, some kinds of primary batteries can
866 * report percentage battery remaining capacity directly to OS.
867 * In this case, it reports the Last Full Charged Capacity == 100
868 * and BatteryPresentRate == 0xFFFFFFFF.
869 *
870 * Now we found some battery reports percentage remaining capacity
871 * even if it's rechargeable.
872 * https://bugzilla.kernel.org/show_bug.cgi?id=15979
873 *
874 * Handle this correctly so that they won't break userspace.
875 */
Lan Tianyu7b786222011-06-30 11:33:27 +0800876static void acpi_battery_quirks(struct acpi_battery *battery)
Zhang Rui557d5862010-10-22 10:02:06 +0800877{
878 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
Nicholas Mazzuca0f4c6542013-05-08 23:11:15 +0000879 return;
Zhang Rui557d5862010-10-22 10:02:06 +0800880
Nicholas Mazzuca0f4c6542013-05-08 23:11:15 +0000881 if (battery->full_charge_capacity == 100 &&
882 battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
883 battery->capacity_now >= 0 && battery->capacity_now <= 100) {
Zhang Rui557d5862010-10-22 10:02:06 +0800884 set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags);
885 battery->full_charge_capacity = battery->design_capacity;
886 battery->capacity_now = (battery->capacity_now *
887 battery->full_charge_capacity) / 100;
888 }
Kamil Iskra4000e622012-11-16 22:28:58 +0100889
890 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags))
Nicholas Mazzuca0f4c6542013-05-08 23:11:15 +0000891 return;
Kamil Iskra4000e622012-11-16 22:28:58 +0100892
893 if (battery->power_unit && dmi_name_in_vendors("LENOVO")) {
894 const char *s;
895 s = dmi_get_system_info(DMI_PRODUCT_VERSION);
Rasmus Villemoesffd8a732014-09-16 22:51:24 +0200896 if (s && !strncasecmp(s, "ThinkPad", 8)) {
Kamil Iskra4000e622012-11-16 22:28:58 +0100897 dmi_walk(find_battery, battery);
898 if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH,
899 &battery->flags) &&
900 battery->design_voltage) {
901 battery->design_capacity =
902 battery->design_capacity *
903 10000 / battery->design_voltage;
904 battery->full_charge_capacity =
905 battery->full_charge_capacity *
906 10000 / battery->design_voltage;
907 battery->design_capacity_warning =
908 battery->design_capacity_warning *
909 10000 / battery->design_voltage;
910 battery->capacity_now = battery->capacity_now *
911 10000 / battery->design_voltage;
912 }
913 }
914 }
Laszlo Totha20136a2018-02-24 10:20:15 +0100915
916 if (test_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags))
917 return;
918
919 if (acpi_battery_is_degraded(battery) &&
920 battery->capacity_now > battery->full_charge_capacity) {
921 set_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags);
922 battery->capacity_now = battery->full_charge_capacity;
923 }
Zhang Rui557d5862010-10-22 10:02:06 +0800924}
925
Lan Tianyu9e50bc12014-05-04 14:07:06 +0800926static int acpi_battery_update(struct acpi_battery *battery, bool resume)
Vladimir Lebedev4bd35cd2007-02-10 01:43:48 -0500927{
Alexey Starikovskiy50b17852008-12-23 02:44:54 +0300928 int result, old_present = acpi_battery_present(battery);
Alexey Starikovskiy97749cd2008-01-01 14:27:24 -0500929 result = acpi_battery_get_status(battery);
Andrey Borzenkov508df922007-10-28 12:50:09 +0300930 if (result)
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300931 return result;
Andrey Borzenkov508df922007-10-28 12:50:09 +0300932 if (!acpi_battery_present(battery)) {
933 sysfs_remove_battery(battery);
Alexey Starikovskiy97749cd2008-01-01 14:27:24 -0500934 battery->update_time = 0;
Andrey Borzenkov508df922007-10-28 12:50:09 +0300935 return 0;
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +0300936 }
Lan Tianyu9e50bc12014-05-04 14:07:06 +0800937
938 if (resume)
939 return 0;
940
Alexey Starikovskiy50b17852008-12-23 02:44:54 +0300941 if (!battery->update_time ||
942 old_present != acpi_battery_present(battery)) {
Alexey Starikovskiy97749cd2008-01-01 14:27:24 -0500943 result = acpi_battery_get_info(battery);
944 if (result)
945 return result;
946 acpi_battery_init_alarm(battery);
947 }
Carlos Garnacho12c78ca2016-08-10 17:24:15 +0200948
949 result = acpi_battery_get_state(battery);
950 if (result)
951 return result;
952 acpi_battery_quirks(battery);
953
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100954 if (!battery->bat) {
Stefan Hajnoczieb03cb02011-07-12 09:03:29 +0100955 result = sysfs_add_battery(battery);
956 if (result)
957 return result;
958 }
Zhang Ruie0d1f092014-05-28 15:23:38 +0800959
960 /*
961 * Wakeup the system if battery is critical low
962 * or lower than the alarm level
963 */
964 if ((battery->state & ACPI_BATTERY_STATE_CRITICAL) ||
965 (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) &&
966 (battery->capacity_now <= battery->alarm)))
Rafael J. Wysocki33e4f802017-06-12 22:56:34 +0200967 acpi_pm_wakeup_event(&battery->device->dev);
Zhang Ruie0d1f092014-05-28 15:23:38 +0800968
Zhang Rui557d5862010-10-22 10:02:06 +0800969 return result;
Vladimir Lebedev4bd35cd2007-02-10 01:43:48 -0500970}
971
Rafael J. Wysockida8aeb92011-01-06 23:42:27 +0100972static void acpi_battery_refresh(struct acpi_battery *battery)
973{
Andy Whitcroftc5971452012-05-03 14:48:26 +0100974 int power_unit;
975
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +0100976 if (!battery->bat)
Rafael J. Wysockida8aeb92011-01-06 23:42:27 +0100977 return;
978
Andy Whitcroftc5971452012-05-03 14:48:26 +0100979 power_unit = battery->power_unit;
980
Rafael J. Wysockida8aeb92011-01-06 23:42:27 +0100981 acpi_battery_get_info(battery);
Andy Whitcroftc5971452012-05-03 14:48:26 +0100982
983 if (power_unit == battery->power_unit)
984 return;
985
986 /* The battery has changed its reporting units. */
Rafael J. Wysockida8aeb92011-01-06 23:42:27 +0100987 sysfs_remove_battery(battery);
988 sysfs_add_battery(battery);
989}
990
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991/* --------------------------------------------------------------------------
Lan Tianyu3a670cc2014-05-04 11:07:25 +0800992 FS Interface (/proc)
993 -------------------------------------------------------------------------- */
994
995#ifdef CONFIG_ACPI_PROCFS_POWER
996static struct proc_dir_entry *acpi_battery_dir;
997
Mathias Krause27059b92015-06-13 14:26:54 +0200998static const char *acpi_battery_units(const struct acpi_battery *battery)
999{
1000 return (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) ?
1001 "mA" : "mW";
1002}
1003
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001004static int acpi_battery_print_info(struct seq_file *seq, int result)
1005{
1006 struct acpi_battery *battery = seq->private;
1007
1008 if (result)
1009 goto end;
1010
1011 seq_printf(seq, "present: %s\n",
1012 acpi_battery_present(battery) ? "yes" : "no");
1013 if (!acpi_battery_present(battery))
1014 goto end;
1015 if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
1016 seq_printf(seq, "design capacity: unknown\n");
1017 else
1018 seq_printf(seq, "design capacity: %d %sh\n",
1019 battery->design_capacity,
1020 acpi_battery_units(battery));
1021
1022 if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
1023 seq_printf(seq, "last full capacity: unknown\n");
1024 else
1025 seq_printf(seq, "last full capacity: %d %sh\n",
1026 battery->full_charge_capacity,
1027 acpi_battery_units(battery));
1028
1029 seq_printf(seq, "battery technology: %srechargeable\n",
1030 (!battery->technology)?"non-":"");
1031
1032 if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
1033 seq_printf(seq, "design voltage: unknown\n");
1034 else
1035 seq_printf(seq, "design voltage: %d mV\n",
1036 battery->design_voltage);
1037 seq_printf(seq, "design capacity warning: %d %sh\n",
1038 battery->design_capacity_warning,
1039 acpi_battery_units(battery));
1040 seq_printf(seq, "design capacity low: %d %sh\n",
1041 battery->design_capacity_low,
1042 acpi_battery_units(battery));
1043 seq_printf(seq, "cycle count: %i\n", battery->cycle_count);
1044 seq_printf(seq, "capacity granularity 1: %d %sh\n",
1045 battery->capacity_granularity_1,
1046 acpi_battery_units(battery));
1047 seq_printf(seq, "capacity granularity 2: %d %sh\n",
1048 battery->capacity_granularity_2,
1049 acpi_battery_units(battery));
1050 seq_printf(seq, "model number: %s\n", battery->model_number);
1051 seq_printf(seq, "serial number: %s\n", battery->serial_number);
1052 seq_printf(seq, "battery type: %s\n", battery->type);
1053 seq_printf(seq, "OEM info: %s\n", battery->oem_info);
1054 end:
1055 if (result)
1056 seq_printf(seq, "ERROR: Unable to read battery info\n");
1057 return result;
1058}
1059
1060static int acpi_battery_print_state(struct seq_file *seq, int result)
1061{
1062 struct acpi_battery *battery = seq->private;
1063
1064 if (result)
1065 goto end;
1066
1067 seq_printf(seq, "present: %s\n",
1068 acpi_battery_present(battery) ? "yes" : "no");
1069 if (!acpi_battery_present(battery))
1070 goto end;
1071
1072 seq_printf(seq, "capacity state: %s\n",
1073 (battery->state & 0x04) ? "critical" : "ok");
1074 if ((battery->state & 0x01) && (battery->state & 0x02))
1075 seq_printf(seq,
1076 "charging state: charging/discharging\n");
1077 else if (battery->state & 0x01)
1078 seq_printf(seq, "charging state: discharging\n");
1079 else if (battery->state & 0x02)
1080 seq_printf(seq, "charging state: charging\n");
1081 else
1082 seq_printf(seq, "charging state: charged\n");
1083
1084 if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
1085 seq_printf(seq, "present rate: unknown\n");
1086 else
1087 seq_printf(seq, "present rate: %d %s\n",
1088 battery->rate_now, acpi_battery_units(battery));
1089
1090 if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
1091 seq_printf(seq, "remaining capacity: unknown\n");
1092 else
1093 seq_printf(seq, "remaining capacity: %d %sh\n",
1094 battery->capacity_now, acpi_battery_units(battery));
1095 if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
1096 seq_printf(seq, "present voltage: unknown\n");
1097 else
1098 seq_printf(seq, "present voltage: %d mV\n",
1099 battery->voltage_now);
1100 end:
1101 if (result)
1102 seq_printf(seq, "ERROR: Unable to read battery state\n");
1103
1104 return result;
1105}
1106
1107static int acpi_battery_print_alarm(struct seq_file *seq, int result)
1108{
1109 struct acpi_battery *battery = seq->private;
1110
1111 if (result)
1112 goto end;
1113
1114 if (!acpi_battery_present(battery)) {
1115 seq_printf(seq, "present: no\n");
1116 goto end;
1117 }
1118 seq_printf(seq, "alarm: ");
1119 if (!battery->alarm)
1120 seq_printf(seq, "unsupported\n");
1121 else
1122 seq_printf(seq, "%u %sh\n", battery->alarm,
1123 acpi_battery_units(battery));
1124 end:
1125 if (result)
1126 seq_printf(seq, "ERROR: Unable to read battery alarm\n");
1127 return result;
1128}
1129
1130static ssize_t acpi_battery_write_alarm(struct file *file,
1131 const char __user * buffer,
1132 size_t count, loff_t * ppos)
1133{
1134 int result = 0;
1135 char alarm_string[12] = { '\0' };
1136 struct seq_file *m = file->private_data;
1137 struct acpi_battery *battery = m->private;
1138
1139 if (!battery || (count > sizeof(alarm_string) - 1))
1140 return -EINVAL;
1141 if (!acpi_battery_present(battery)) {
1142 result = -ENODEV;
1143 goto end;
1144 }
1145 if (copy_from_user(alarm_string, buffer, count)) {
1146 result = -EFAULT;
1147 goto end;
1148 }
1149 alarm_string[count] = '\0';
Christoph Jaeger3d915892014-06-13 21:49:58 +02001150 if (kstrtoint(alarm_string, 0, &battery->alarm)) {
1151 result = -EINVAL;
1152 goto end;
1153 }
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001154 result = acpi_battery_set_alarm(battery);
1155 end:
1156 if (!result)
1157 return count;
1158 return result;
1159}
1160
1161typedef int(*print_func)(struct seq_file *seq, int result);
1162
1163static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = {
1164 acpi_battery_print_info,
1165 acpi_battery_print_state,
1166 acpi_battery_print_alarm,
1167};
1168
1169static int acpi_battery_read(int fid, struct seq_file *seq)
1170{
1171 struct acpi_battery *battery = seq->private;
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001172 int result = acpi_battery_update(battery, false);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001173 return acpi_print_funcs[fid](seq, result);
1174}
1175
1176#define DECLARE_FILE_FUNCTIONS(_name) \
1177static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \
1178{ \
1179 return acpi_battery_read(_name##_tag, seq); \
1180} \
1181static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \
1182{ \
1183 return single_open(file, acpi_battery_read_##_name, PDE_DATA(inode)); \
1184}
1185
1186DECLARE_FILE_FUNCTIONS(info);
1187DECLARE_FILE_FUNCTIONS(state);
1188DECLARE_FILE_FUNCTIONS(alarm);
1189
1190#undef DECLARE_FILE_FUNCTIONS
1191
1192#define FILE_DESCRIPTION_RO(_name) \
1193 { \
1194 .name = __stringify(_name), \
1195 .mode = S_IRUGO, \
1196 .ops = { \
1197 .open = acpi_battery_##_name##_open_fs, \
1198 .read = seq_read, \
1199 .llseek = seq_lseek, \
1200 .release = single_release, \
1201 .owner = THIS_MODULE, \
1202 }, \
1203 }
1204
1205#define FILE_DESCRIPTION_RW(_name) \
1206 { \
1207 .name = __stringify(_name), \
1208 .mode = S_IFREG | S_IRUGO | S_IWUSR, \
1209 .ops = { \
1210 .open = acpi_battery_##_name##_open_fs, \
1211 .read = seq_read, \
1212 .llseek = seq_lseek, \
1213 .write = acpi_battery_write_##_name, \
1214 .release = single_release, \
1215 .owner = THIS_MODULE, \
1216 }, \
1217 }
1218
1219static const struct battery_file {
1220 struct file_operations ops;
1221 umode_t mode;
1222 const char *name;
1223} acpi_battery_file[] = {
1224 FILE_DESCRIPTION_RO(info),
1225 FILE_DESCRIPTION_RO(state),
1226 FILE_DESCRIPTION_RW(alarm),
1227};
1228
1229#undef FILE_DESCRIPTION_RO
1230#undef FILE_DESCRIPTION_RW
1231
1232static int acpi_battery_add_fs(struct acpi_device *device)
1233{
1234 struct proc_dir_entry *entry = NULL;
1235 int i;
1236
1237 printk(KERN_WARNING PREFIX "Deprecated procfs I/F for battery is loaded,"
1238 " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n");
1239 if (!acpi_device_dir(device)) {
1240 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
1241 acpi_battery_dir);
1242 if (!acpi_device_dir(device))
1243 return -ENODEV;
1244 }
1245
1246 for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
1247 entry = proc_create_data(acpi_battery_file[i].name,
1248 acpi_battery_file[i].mode,
1249 acpi_device_dir(device),
1250 &acpi_battery_file[i].ops,
1251 acpi_driver_data(device));
1252 if (!entry)
1253 return -ENODEV;
1254 }
1255 return 0;
1256}
1257
1258static void acpi_battery_remove_fs(struct acpi_device *device)
1259{
1260 int i;
1261 if (!acpi_device_dir(device))
1262 return;
1263 for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i)
1264 remove_proc_entry(acpi_battery_file[i].name,
1265 acpi_device_dir(device));
1266
1267 remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
1268 acpi_device_dir(device) = NULL;
1269}
1270
1271#endif
1272
1273/* --------------------------------------------------------------------------
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274 Driver Interface
1275 -------------------------------------------------------------------------- */
1276
Bjorn Helgaasd9406692009-04-30 09:35:47 -06001277static void acpi_battery_notify(struct acpi_device *device, u32 event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001278{
Bjorn Helgaasd9406692009-04-30 09:35:47 -06001279 struct acpi_battery *battery = acpi_driver_data(device);
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +01001280 struct power_supply *old;
Bjorn Helgaasd9406692009-04-30 09:35:47 -06001281
Linus Torvalds1da177e2005-04-16 15:20:36 -07001282 if (!battery)
Patrick Mocheld550d982006-06-27 00:41:40 -04001283 return;
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +01001284 old = battery->bat;
Alexander Mezinf43691c2014-06-04 02:01:23 +07001285 /*
1286 * On Acer Aspire V5-573G notifications are sometimes triggered too
1287 * early. For example, when AC is unplugged and notification is
1288 * triggered, battery state is still reported as "Full", and changes to
1289 * "Discharging" only after short delay, without any notification.
1290 */
1291 if (battery_notification_delay_ms > 0)
1292 msleep(battery_notification_delay_ms);
Rafael J. Wysockida8aeb92011-01-06 23:42:27 +01001293 if (event == ACPI_BATTERY_NOTIFY_INFO)
1294 acpi_battery_refresh(battery);
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001295 acpi_battery_update(battery, false);
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +04001296 acpi_bus_generate_netlink_event(device->pnp.device_class,
Kay Sievers07944692008-10-30 01:18:59 +01001297 dev_name(&device->dev), event,
Vladimir Lebedev9ea7d572007-02-20 15:48:06 +03001298 acpi_battery_present(battery));
Alexander Mezin411e0f72014-03-12 00:58:47 +07001299 acpi_notifier_call_chain(device, event, acpi_battery_present(battery));
Justin P. Mattock2345baf2009-12-13 14:42:36 -08001300 /* acpi_battery_update could remove power_supply object */
Krzysztof Kozlowski297d7162015-03-12 08:44:11 +01001301 if (old && battery->bat)
1302 power_supply_changed(battery->bat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001303}
1304
Kyle McMartin25be5822011-03-22 16:19:50 -04001305static int battery_notify(struct notifier_block *nb,
1306 unsigned long mode, void *_unused)
1307{
1308 struct acpi_battery *battery = container_of(nb, struct acpi_battery,
1309 pm_nb);
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001310 int result;
1311
Kyle McMartin25be5822011-03-22 16:19:50 -04001312 switch (mode) {
Lan Tianyud5a59112011-06-30 11:33:40 +08001313 case PM_POST_HIBERNATION:
Kyle McMartin25be5822011-03-22 16:19:50 -04001314 case PM_POST_SUSPEND:
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001315 if (!acpi_battery_present(battery))
1316 return 0;
1317
Krzysztof Kozlowski31f7dc72015-04-14 22:24:13 +09001318 if (!battery->bat) {
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001319 result = acpi_battery_get_info(battery);
1320 if (result)
1321 return result;
1322
1323 result = sysfs_add_battery(battery);
1324 if (result)
1325 return result;
1326 } else
1327 acpi_battery_refresh(battery);
1328
1329 acpi_battery_init_alarm(battery);
1330 acpi_battery_get_state(battery);
Kyle McMartin25be5822011-03-22 16:19:50 -04001331 break;
1332 }
1333
1334 return 0;
1335}
1336
Mathias Krause048d16d2015-06-13 14:26:55 +02001337static int __init
1338battery_bix_broken_package_quirk(const struct dmi_system_id *d)
Alexander Mezin3f5dc082014-06-04 02:01:22 +07001339{
1340 battery_bix_broken_package = 1;
1341 return 0;
1342}
1343
Mathias Krause048d16d2015-06-13 14:26:55 +02001344static int __init
1345battery_notification_delay_quirk(const struct dmi_system_id *d)
Alexander Mezinf43691c2014-06-04 02:01:23 +07001346{
1347 battery_notification_delay_ms = 1000;
1348 return 0;
1349}
1350
Hans de Goede1b799c52018-04-12 12:02:00 +02001351static int __init
1352battery_ac_is_broken_quirk(const struct dmi_system_id *d)
1353{
1354 battery_ac_is_broken = 1;
1355 return 0;
1356}
1357
Carlo Caioneec625a32018-04-18 14:04:39 +02001358static int __init
1359battery_do_not_check_pmic_quirk(const struct dmi_system_id *d)
1360{
1361 battery_check_pmic = 0;
1362 return 0;
1363}
1364
Mathias Krause048d16d2015-06-13 14:26:55 +02001365static const struct dmi_system_id bat_dmi_table[] __initconst = {
Lan Tianyua90b4032014-01-06 22:50:37 +08001366 {
Hans de Goede91afa072018-04-12 12:01:58 +02001367 /* NEC LZ750/LS */
Alexander Mezin3f5dc082014-06-04 02:01:22 +07001368 .callback = battery_bix_broken_package_quirk,
Lan Tianyua90b4032014-01-06 22:50:37 +08001369 .matches = {
1370 DMI_MATCH(DMI_SYS_VENDOR, "NEC"),
1371 DMI_MATCH(DMI_PRODUCT_NAME, "PC-LZ750LS"),
1372 },
1373 },
Alexander Mezinf43691c2014-06-04 02:01:23 +07001374 {
Hans de Goede91afa072018-04-12 12:01:58 +02001375 /* Acer Aspire V5-573G */
Alexander Mezinf43691c2014-06-04 02:01:23 +07001376 .callback = battery_notification_delay_quirk,
Alexander Mezinf43691c2014-06-04 02:01:23 +07001377 .matches = {
1378 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
1379 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-573G"),
1380 },
1381 },
Hans de Goede1b799c52018-04-12 12:02:00 +02001382 {
1383 /* Point of View mobii wintab p800w */
1384 .callback = battery_ac_is_broken_quirk,
1385 .matches = {
1386 DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
1387 DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
1388 DMI_MATCH(DMI_BIOS_VERSION, "3BAIR1013"),
1389 /* Above matches are too generic, add bios-date match */
1390 DMI_MATCH(DMI_BIOS_DATE, "08/22/2014"),
1391 },
1392 },
Carlo Caioneec625a32018-04-18 14:04:39 +02001393 {
1394 /* ECS EF20EA */
1395 .callback = battery_do_not_check_pmic_quirk,
1396 .matches = {
1397 DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"),
1398 },
1399 },
1400 {
1401 /* Lenovo Ideapad Miix 320 */
1402 .callback = battery_do_not_check_pmic_quirk,
1403 .matches = {
1404 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
1405 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80XF"),
1406 DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
1407 },
1408 },
Lan Tianyua90b4032014-01-06 22:50:37 +08001409 {},
1410};
1411
Lan Tianyu75646e72014-07-07 15:47:12 +08001412/*
1413 * Some machines'(E,G Lenovo Z480) ECs are not stable
1414 * during boot up and this causes battery driver fails to be
1415 * probed due to failure of getting battery information
1416 * from EC sometimes. After several retries, the operation
1417 * may work. So add retry code here and 20ms sleep between
1418 * every retries.
1419 */
1420static int acpi_battery_update_retry(struct acpi_battery *battery)
1421{
1422 int retry, ret;
1423
1424 for (retry = 5; retry; retry--) {
1425 ret = acpi_battery_update(battery, false);
1426 if (!ret)
1427 break;
1428
1429 msleep(20);
1430 }
1431 return ret;
1432}
1433
Len Brown4be44fc2005-08-05 00:44:28 -04001434static int acpi_battery_add(struct acpi_device *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001435{
Len Brown4be44fc2005-08-05 00:44:28 -04001436 int result = 0;
Len Brown4be44fc2005-08-05 00:44:28 -04001437 struct acpi_battery *battery = NULL;
Jiang Liu952c63e2013-06-29 00:24:38 +08001438
Linus Torvalds1da177e2005-04-16 15:20:36 -07001439 if (!device)
Patrick Mocheld550d982006-06-27 00:41:40 -04001440 return -EINVAL;
Lan Tianyu40e7fcb2014-11-23 21:22:54 +08001441
1442 if (device->dep_unmet)
1443 return -EPROBE_DEFER;
1444
Burman Yan36bcbec2006-12-19 12:56:11 -08001445 battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446 if (!battery)
Patrick Mocheld550d982006-06-27 00:41:40 -04001447 return -ENOMEM;
Patrick Mochel145def82006-05-19 16:54:39 -04001448 battery->device = device;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001449 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
1450 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
Pavel Machekdb89b4f2008-09-22 14:37:34 -07001451 device->driver_data = battery;
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +04001452 mutex_init(&battery->lock);
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +03001453 mutex_init(&battery->sysfs_lock);
Jiang Liu952c63e2013-06-29 00:24:38 +08001454 if (acpi_has_method(battery->device->handle, "_BIX"))
Alexey Starikovskiyc67fcd62009-10-15 14:31:44 +04001455 set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
Lan Tianyu75646e72014-07-07 15:47:12 +08001456
1457 result = acpi_battery_update_retry(battery);
Stefan Hajnoczieb03cb02011-07-12 09:03:29 +01001458 if (result)
1459 goto fail;
Lan Tianyu75646e72014-07-07 15:47:12 +08001460
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001461#ifdef CONFIG_ACPI_PROCFS_POWER
1462 result = acpi_battery_add_fs(device);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001463 if (result) {
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001464 acpi_battery_remove_fs(device);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001465 goto fail;
1466 }
Bjørn Mork6993ce42017-12-05 18:46:39 +01001467#endif
Kyle McMartin25be5822011-03-22 16:19:50 -04001468
Stefan Hajnoczie80bba42011-07-12 09:03:28 +01001469 printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
1470 ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
1471 device->status.battery_present ? "present" : "absent");
1472
Kyle McMartin25be5822011-03-22 16:19:50 -04001473 battery->pm_nb.notifier_call = battery_notify;
1474 register_pm_notifier(&battery->pm_nb);
1475
Zhang Ruie0d1f092014-05-28 15:23:38 +08001476 device_init_wakeup(&device->dev, 1);
1477
Patrick Mocheld550d982006-06-27 00:41:40 -04001478 return result;
Stefan Hajnoczie80bba42011-07-12 09:03:28 +01001479
1480fail:
1481 sysfs_remove_battery(battery);
1482 mutex_destroy(&battery->lock);
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +03001483 mutex_destroy(&battery->sysfs_lock);
Stefan Hajnoczie80bba42011-07-12 09:03:28 +01001484 kfree(battery);
1485 return result;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486}
1487
Rafael J. Wysocki51fac832013-01-24 00:24:48 +01001488static int acpi_battery_remove(struct acpi_device *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489{
Len Brown4be44fc2005-08-05 00:44:28 -04001490 struct acpi_battery *battery = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492 if (!device || !acpi_driver_data(device))
Patrick Mocheld550d982006-06-27 00:41:40 -04001493 return -EINVAL;
Zhang Ruie0d1f092014-05-28 15:23:38 +08001494 device_init_wakeup(&device->dev, 0);
Jan Engelhardt50dd0962006-10-01 00:28:50 +02001495 battery = acpi_driver_data(device);
Kyle McMartin25be5822011-03-22 16:19:50 -04001496 unregister_pm_notifier(&battery->pm_nb);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001497#ifdef CONFIG_ACPI_PROCFS_POWER
1498 acpi_battery_remove_fs(device);
1499#endif
Andrey Borzenkov508df922007-10-28 12:50:09 +03001500 sysfs_remove_battery(battery);
Alexey Starikovskiy038fdea2007-09-26 19:42:46 +04001501 mutex_destroy(&battery->lock);
Sergey Senozhatsky69d94ec2011-08-06 01:34:08 +03001502 mutex_destroy(&battery->sysfs_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001503 kfree(battery);
Patrick Mocheld550d982006-06-27 00:41:40 -04001504 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001505}
1506
Rafael J. Wysocki90692402012-08-09 23:00:02 +02001507#ifdef CONFIG_PM_SLEEP
Jiri Kosina34c44152006-10-10 14:20:41 -07001508/* this is needed to learn about changes made in suspended state */
Rafael J. Wysockia6f50dc2012-06-27 23:26:43 +02001509static int acpi_battery_resume(struct device *dev)
Jiri Kosina34c44152006-10-10 14:20:41 -07001510{
1511 struct acpi_battery *battery;
Rafael J. Wysockia6f50dc2012-06-27 23:26:43 +02001512
1513 if (!dev)
Jiri Kosina34c44152006-10-10 14:20:41 -07001514 return -EINVAL;
Rafael J. Wysockia6f50dc2012-06-27 23:26:43 +02001515
1516 battery = acpi_driver_data(to_acpi_device(dev));
1517 if (!battery)
1518 return -EINVAL;
1519
Alexey Starikovskiyf1d46612007-09-26 19:42:52 +04001520 battery->update_time = 0;
Lan Tianyu9e50bc12014-05-04 14:07:06 +08001521 acpi_battery_update(battery, true);
Vladimir Lebedevb6ce4082007-02-20 15:48:06 +03001522 return 0;
Jiri Kosina34c44152006-10-10 14:20:41 -07001523}
Shuah Khan7f6895c2014-02-12 20:19:06 -07001524#else
1525#define acpi_battery_resume NULL
Rafael J. Wysocki90692402012-08-09 23:00:02 +02001526#endif
Jiri Kosina34c44152006-10-10 14:20:41 -07001527
Rafael J. Wysockia6f50dc2012-06-27 23:26:43 +02001528static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume);
1529
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +04001530static struct acpi_driver acpi_battery_driver = {
1531 .name = "battery",
1532 .class = ACPI_BATTERY_CLASS,
1533 .ids = battery_device_ids,
Bjorn Helgaasd9406692009-04-30 09:35:47 -06001534 .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +04001535 .ops = {
1536 .add = acpi_battery_add,
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +04001537 .remove = acpi_battery_remove,
Bjorn Helgaasd9406692009-04-30 09:35:47 -06001538 .notify = acpi_battery_notify,
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +04001539 },
Rafael J. Wysockia6f50dc2012-06-27 23:26:43 +02001540 .drv.pm = &acpi_battery_pm,
Alexey Starikovskiyaa650bb2007-09-26 19:42:58 +04001541};
1542
Linus Torvaldsb0cbc862009-04-11 12:45:20 -07001543static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544{
Hans de Goededccfae62017-04-19 14:02:10 +02001545 unsigned int i;
Luis Henriques479faaf2015-05-11 22:48:46 +01001546 int result;
1547
Alexander Mezin3f5dc082014-06-04 02:01:22 +07001548 dmi_check_system(bat_dmi_table);
Luis Henriques479faaf2015-05-11 22:48:46 +01001549
Carlo Caioneec625a32018-04-18 14:04:39 +02001550 if (battery_check_pmic) {
1551 for (i = 0; i < ARRAY_SIZE(acpi_battery_blacklist); i++)
1552 if (acpi_dev_present(acpi_battery_blacklist[i], "1", -1)) {
1553 pr_info(PREFIX ACPI_BATTERY_DEVICE_NAME
1554 ": found native %s PMIC, not loading\n",
1555 acpi_battery_blacklist[i]);
1556 return;
1557 }
1558 }
1559
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001560#ifdef CONFIG_ACPI_PROCFS_POWER
1561 acpi_battery_dir = acpi_lock_battery_dir();
1562 if (!acpi_battery_dir)
1563 return;
1564#endif
Luis Henriques479faaf2015-05-11 22:48:46 +01001565 result = acpi_bus_register_driver(&acpi_battery_driver);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001566#ifdef CONFIG_ACPI_PROCFS_POWER
Luis Henriques479faaf2015-05-11 22:48:46 +01001567 if (result < 0)
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001568 acpi_unlock_battery_dir(acpi_battery_dir);
1569#endif
Hans de Goedebc39fbc2017-04-19 14:02:09 +02001570 battery_driver_registered = (result == 0);
Arjan van de Ven0f66af52009-01-10 14:19:05 -05001571}
1572
1573static int __init acpi_battery_init(void)
1574{
Luis Henriquese234b072015-05-11 22:48:38 +01001575 if (acpi_disabled)
1576 return -ENODEV;
1577
Luis Henriqueseca21d912015-05-11 22:49:05 +01001578 async_cookie = async_schedule(acpi_battery_init_async, NULL);
Patrick Mocheld550d982006-06-27 00:41:40 -04001579 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580}
1581
Len Brown4be44fc2005-08-05 00:44:28 -04001582static void __exit acpi_battery_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583{
Chris Wilson5dfa0c72016-05-19 09:11:52 +01001584 async_synchronize_cookie(async_cookie + 1);
Ognjen Galicfa938542018-02-07 15:58:13 +01001585 if (battery_driver_registered) {
Hans de Goedebc39fbc2017-04-19 14:02:09 +02001586 acpi_bus_unregister_driver(&acpi_battery_driver);
Ognjen Galicfa938542018-02-07 15:58:13 +01001587 battery_hook_exit();
1588 }
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001589#ifdef CONFIG_ACPI_PROCFS_POWER
Hans de Goedebc39fbc2017-04-19 14:02:09 +02001590 if (acpi_battery_dir)
1591 acpi_unlock_battery_dir(acpi_battery_dir);
Lan Tianyu3a670cc2014-05-04 11:07:25 +08001592#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593}
1594
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595module_init(acpi_battery_init);
1596module_exit(acpi_battery_exit);