Blame view
drivers/acpi/battery.c
37.8 KB
c942fddf8 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
1da177e4c Linux-2.6.12-rc2 |
2 |
/* |
aa650bbdc ACPI: Battery: Mi... |
3 |
* battery.c - ACPI Battery Driver (Revision: 2.0) |
1da177e4c Linux-2.6.12-rc2 |
4 |
* |
aa650bbdc ACPI: Battery: Mi... |
5 6 |
* Copyright (C) 2007 Alexey Starikovskiy <astarikovskiy@suse.de> * Copyright (C) 2004-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com> |
1da177e4c Linux-2.6.12-rc2 |
7 8 |
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> |
1da177e4c Linux-2.6.12-rc2 |
9 |
*/ |
fa93854f7 battery: Add the ... |
10 |
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
53dd200a2 ACPI / battery: r... |
11 12 13 14 |
#include <linux/async.h> #include <linux/delay.h> #include <linux/dmi.h> #include <linux/jiffies.h> |
1da177e4c Linux-2.6.12-rc2 |
15 |
#include <linux/kernel.h> |
fa93854f7 battery: Add the ... |
16 |
#include <linux/list.h> |
1da177e4c Linux-2.6.12-rc2 |
17 |
#include <linux/module.h> |
fa93854f7 battery: Add the ... |
18 |
#include <linux/mutex.h> |
5a0e3ad6a include cleanup: ... |
19 |
#include <linux/slab.h> |
25be58215 ACPI battery: fri... |
20 |
#include <linux/suspend.h> |
53dd200a2 ACPI / battery: r... |
21 |
#include <linux/types.h> |
4000e6261 ACPI / battery: C... |
22 |
#include <asm/unaligned.h> |
d73809657 ACPI: Battery: Ad... |
23 |
|
8b48463f8 ACPI: Clean up in... |
24 |
#include <linux/acpi.h> |
d73809657 ACPI: Battery: Ad... |
25 |
#include <linux/power_supply.h> |
fa93854f7 battery: Add the ... |
26 |
#include <acpi/battery.h> |
f03be3525 ACPI / battery: m... |
27 |
|
a192a9580 ACPI: Move defini... |
28 |
#define PREFIX "ACPI: " |
1da177e4c Linux-2.6.12-rc2 |
29 |
#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF |
cc99f0ad5 ACPI / battery: D... |
30 31 |
#define ACPI_BATTERY_CAPACITY_VALID(capacity) \ ((capacity) != 0 && (capacity) != ACPI_BATTERY_VALUE_UNKNOWN) |
1da177e4c Linux-2.6.12-rc2 |
32 |
|
1da177e4c Linux-2.6.12-rc2 |
33 |
#define ACPI_BATTERY_DEVICE_NAME "Battery" |
1da177e4c Linux-2.6.12-rc2 |
34 |
|
ae6f61870 ACPI / Battery: A... |
35 36 |
/* Battery power unit: 0 means mW, 1 means mA */ #define ACPI_BATTERY_POWER_UNIT_MA 1 |
1ac5aaa67 ACPI / battery: i... |
37 38 39 |
#define ACPI_BATTERY_STATE_DISCHARGING 0x1 #define ACPI_BATTERY_STATE_CHARGING 0x2 #define ACPI_BATTERY_STATE_CRITICAL 0x4 |
1da177e4c Linux-2.6.12-rc2 |
40 |
#define _COMPONENT ACPI_BATTERY_COMPONENT |
b6ce4083e ACPI: Cache batte... |
41 |
|
f52fd66d2 ACPI: clean up AC... |
42 |
ACPI_MODULE_NAME("battery"); |
1da177e4c Linux-2.6.12-rc2 |
43 |
|
f52fd66d2 ACPI: clean up AC... |
44 |
MODULE_AUTHOR("Paul Diefenbaugh"); |
aa650bbdc ACPI: Battery: Mi... |
45 |
MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>"); |
7cda93e00 ACPI: delete extr... |
46 |
MODULE_DESCRIPTION("ACPI Battery Driver"); |
1da177e4c Linux-2.6.12-rc2 |
47 |
MODULE_LICENSE("GPL"); |
eca21d916 ACPI / battery: e... |
48 |
static async_cookie_t async_cookie; |
bc39fbcf9 ACPI / battery: F... |
49 |
static bool battery_driver_registered; |
a90b40385 ACPI / Battery: A... |
50 |
static int battery_bix_broken_package; |
f43691c61 ACPI / battery: a... |
51 |
static int battery_notification_delay_ms; |
1b799c5cf ACPI / battery: I... |
52 |
static int battery_ac_is_broken; |
ec625a37c ACPI / battery: A... |
53 |
static int battery_check_pmic = 1; |
f1d4661ab ACPI: Battery: si... |
54 55 56 |
static unsigned int cache_time = 1000; module_param(cache_time, uint, 0644); MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); |
b6ce4083e ACPI: Cache batte... |
57 |
|
1ba90e3a8 ACPI: autoload mo... |
58 59 60 61 |
static const struct acpi_device_id battery_device_ids[] = { {"PNP0C0A", 0}, {"", 0}, }; |
1ba90e3a8 ACPI: autoload mo... |
62 |
|
aa650bbdc ACPI: Battery: Mi... |
63 |
MODULE_DEVICE_TABLE(acpi, battery_device_ids); |
1da177e4c Linux-2.6.12-rc2 |
64 |
|
dccfae6d4 ACPI / battery: A... |
65 66 67 68 |
/* Lists of PMIC ACPI HIDs with an (often better) native battery driver */ static const char * const acpi_battery_blacklist[] = { "INT33F4", /* X-Powers AXP288 PMIC */ }; |
7b3bcc4a1 ACPI: Battery: Ad... |
69 70 |
enum { ACPI_BATTERY_ALARM_PRESENT, |
c67fcd670 ACPI: Battery: Ad... |
71 |
ACPI_BATTERY_XINFO_PRESENT, |
557d58687 ACPI battery: sup... |
72 |
ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, |
4000e6261 ACPI / battery: C... |
73 74 75 76 77 78 79 80 81 82 83 84 |
/* On Lenovo Thinkpad models from 2010 and 2011, the power unit switches between mWh and mAh depending on whether the system is running on battery or not. When mAh is the unit, most reported values are incorrect and need to be adjusted by 10000/design_voltage. Verified on x201, t410, t410s, and x220. Pre-2010 and 2012 models appear to always report in mWh and are thus unaffected (tested with t42, t61, t500, x200, x300, and x230). Also, in mid-2012 Lenovo issued a BIOS update for the 2011 models that fixes the issue (tested on x220 with a post-1.29 BIOS), but as of Nov. 2012, no such update is available for the 2010 models. */ ACPI_BATTERY_QUIRK_THINKPAD_MAH, |
a20136a67 ACPI: battery: do... |
85 86 87 88 |
/* for batteries reporting current capacity with design capacity * on a full charge, but showing degradation in full charge cap. */ ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, |
7b3bcc4a1 ACPI: Battery: Ad... |
89 |
}; |
78490d821 ACPI: battery: sy... |
90 |
|
1da177e4c Linux-2.6.12-rc2 |
91 |
struct acpi_battery { |
038fdea29 ACPI: Battery: do... |
92 |
struct mutex lock; |
69d94ec6d Battery: sysfs_re... |
93 |
struct mutex sysfs_lock; |
297d716f6 power_supply: Cha... |
94 95 |
struct power_supply *bat; struct power_supply_desc bat_desc; |
f1d4661ab ACPI: Battery: si... |
96 |
struct acpi_device *device; |
25be58215 ACPI battery: fri... |
97 |
struct notifier_block pm_nb; |
fa93854f7 battery: Add the ... |
98 |
struct list_head list; |
f1d4661ab ACPI: Battery: si... |
99 |
unsigned long update_time; |
016d5baad ACPI / battery: F... |
100 |
int revision; |
7faa144a5 ACPI: battery: ad... |
101 |
int rate_now; |
d73809657 ACPI: Battery: Ad... |
102 103 |
int capacity_now; int voltage_now; |
038fdea29 ACPI: Battery: do... |
104 |
int design_capacity; |
d73809657 ACPI: Battery: Ad... |
105 |
int full_charge_capacity; |
038fdea29 ACPI: Battery: do... |
106 107 108 109 |
int technology; int design_voltage; int design_capacity_warning; int design_capacity_low; |
c67fcd670 ACPI: Battery: Ad... |
110 111 112 113 114 115 |
int cycle_count; int measurement_accuracy; int max_sampling_time; int min_sampling_time; int max_averaging_interval; int min_averaging_interval; |
038fdea29 ACPI: Battery: do... |
116 117 |
int capacity_granularity_1; int capacity_granularity_2; |
f1d4661ab ACPI: Battery: si... |
118 |
int alarm; |
038fdea29 ACPI: Battery: do... |
119 120 121 122 |
char model_number[32]; char serial_number[32]; char type[32]; char oem_info[32]; |
f1d4661ab ACPI: Battery: si... |
123 124 |
int state; int power_unit; |
7b3bcc4a1 ACPI: Battery: Ad... |
125 |
unsigned long flags; |
1da177e4c Linux-2.6.12-rc2 |
126 |
}; |
297d716f6 power_supply: Cha... |
127 |
#define to_acpi_battery(x) power_supply_get_drvdata(x) |
d73809657 ACPI: Battery: Ad... |
128 |
|
efd941f10 ACPI: suppress co... |
129 |
static inline int acpi_battery_present(struct acpi_battery *battery) |
b6ce4083e ACPI: Cache batte... |
130 |
{ |
78490d821 ACPI: battery: sy... |
131 132 |
return battery->device->status.battery_present; } |
038fdea29 ACPI: Battery: do... |
133 |
|
d73809657 ACPI: Battery: Ad... |
134 135 136 137 138 139 140 141 |
static int acpi_battery_technology(struct acpi_battery *battery) { if (!strcasecmp("NiCd", battery->type)) return POWER_SUPPLY_TECHNOLOGY_NiCd; if (!strcasecmp("NiMH", battery->type)) return POWER_SUPPLY_TECHNOLOGY_NiMH; if (!strcasecmp("LION", battery->type)) return POWER_SUPPLY_TECHNOLOGY_LION; |
ad40e68bf ACPI: battery: fi... |
142 |
if (!strncasecmp("LI-ION", battery->type, 6)) |
0bde7eee9 ACPI: battery: Su... |
143 |
return POWER_SUPPLY_TECHNOLOGY_LION; |
d73809657 ACPI: Battery: Ad... |
144 145 146 147 |
if (!strcasecmp("LiP", battery->type)) return POWER_SUPPLY_TECHNOLOGY_LIPO; return POWER_SUPPLY_TECHNOLOGY_UNKNOWN; } |
9104476e4 ACPI: Battery: re... |
148 |
static int acpi_battery_get_state(struct acpi_battery *battery); |
b19073a0b ACPI: battery: Up... |
149 |
|
56f382a08 battery: don't as... |
150 151 |
static int acpi_battery_is_charged(struct acpi_battery *battery) { |
1ac5aaa67 ACPI / battery: i... |
152 |
/* charging, discharging or critical low */ |
56f382a08 battery: don't as... |
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
if (battery->state != 0) return 0; /* battery not reporting charge */ if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN || battery->capacity_now == 0) return 0; /* good batteries update full_charge as the batteries degrade */ if (battery->full_charge_capacity == battery->capacity_now) return 1; /* fallback to using design values for broken batteries */ if (battery->design_capacity == battery->capacity_now) return 1; /* we don't do any sort of metric based on percentages */ return 0; } |
a20136a67 ACPI: battery: do... |
172 173 |
static bool acpi_battery_is_degraded(struct acpi_battery *battery) { |
cc99f0ad5 ACPI / battery: D... |
174 175 |
return ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) && ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity) && |
a20136a67 ACPI: battery: do... |
176 177 |
battery->full_charge_capacity < battery->design_capacity; } |
19fffc845 ACPI / battery: A... |
178 179 180 181 182 183 184 |
static int acpi_battery_handle_discharging(struct acpi_battery *battery) { /* * Some devices wrongly report discharging if the battery's charge level * was above the device's start charging threshold atm the AC adapter * was plugged in and the device thus did not start a new charge cycle. */ |
1b799c5cf ACPI / battery: I... |
185 186 |
if ((battery_ac_is_broken || power_supply_is_system_supplied()) && battery->rate_now == 0) |
19fffc845 ACPI / battery: A... |
187 188 189 190 |
return POWER_SUPPLY_STATUS_NOT_CHARGING; return POWER_SUPPLY_STATUS_DISCHARGING; } |
d73809657 ACPI: Battery: Ad... |
191 192 193 194 |
static int acpi_battery_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) { |
5b74d1d16 ACPI / battery: U... |
195 |
int full_capacity = ACPI_BATTERY_VALUE_UNKNOWN, ret = 0; |
d73809657 ACPI: Battery: Ad... |
196 |
struct acpi_battery *battery = to_acpi_battery(psy); |
9104476e4 ACPI: Battery: re... |
197 198 199 200 |
if (acpi_battery_present(battery)) { /* run battery update only if it is present */ acpi_battery_get_state(battery); } else if (psp != POWER_SUPPLY_PROP_PRESENT) |
d73809657 ACPI: Battery: Ad... |
201 202 203 |
return -ENODEV; switch (psp) { case POWER_SUPPLY_PROP_STATUS: |
82bf43b29 Revert "ACPI / ba... |
204 |
if (battery->state & ACPI_BATTERY_STATE_DISCHARGING) |
19fffc845 ACPI / battery: A... |
205 |
val->intval = acpi_battery_handle_discharging(battery); |
82bf43b29 Revert "ACPI / ba... |
206 |
else if (battery->state & ACPI_BATTERY_STATE_CHARGING) |
d73809657 ACPI: Battery: Ad... |
207 |
val->intval = POWER_SUPPLY_STATUS_CHARGING; |
56f382a08 battery: don't as... |
208 |
else if (acpi_battery_is_charged(battery)) |
d73809657 ACPI: Battery: Ad... |
209 |
val->intval = POWER_SUPPLY_STATUS_FULL; |
4c41d3ad6 ACPI: Always retu... |
210 211 |
else val->intval = POWER_SUPPLY_STATUS_UNKNOWN; |
d73809657 ACPI: Battery: Ad... |
212 213 214 215 216 217 218 |
break; case POWER_SUPPLY_PROP_PRESENT: val->intval = acpi_battery_present(battery); break; case POWER_SUPPLY_PROP_TECHNOLOGY: val->intval = acpi_battery_technology(battery); break; |
c67fcd670 ACPI: Battery: Ad... |
219 220 221 |
case POWER_SUPPLY_PROP_CYCLE_COUNT: val->intval = battery->cycle_count; break; |
d73809657 ACPI: Battery: Ad... |
222 |
case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: |
a1b4bd694 ACPI / Battery: R... |
223 224 225 226 |
if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) ret = -ENODEV; else val->intval = battery->design_voltage * 1000; |
d73809657 ACPI: Battery: Ad... |
227 228 |
break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: |
a1b4bd694 ACPI / Battery: R... |
229 230 231 232 |
if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN) ret = -ENODEV; else val->intval = battery->voltage_now * 1000; |
d73809657 ACPI: Battery: Ad... |
233 234 |
break; case POWER_SUPPLY_PROP_CURRENT_NOW: |
7faa144a5 ACPI: battery: ad... |
235 |
case POWER_SUPPLY_PROP_POWER_NOW: |
a1b4bd694 ACPI / Battery: R... |
236 237 238 239 |
if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN) ret = -ENODEV; else val->intval = battery->rate_now * 1000; |
d73809657 ACPI: Battery: Ad... |
240 241 242 |
break; case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: |
cc99f0ad5 ACPI / battery: D... |
243 |
if (!ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity)) |
a1b4bd694 ACPI / Battery: R... |
244 245 246 |
ret = -ENODEV; else val->intval = battery->design_capacity * 1000; |
d73809657 ACPI: Battery: Ad... |
247 248 249 |
break; case POWER_SUPPLY_PROP_CHARGE_FULL: case POWER_SUPPLY_PROP_ENERGY_FULL: |
cc99f0ad5 ACPI / battery: D... |
250 |
if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity)) |
a1b4bd694 ACPI / Battery: R... |
251 252 253 |
ret = -ENODEV; else val->intval = battery->full_charge_capacity * 1000; |
d73809657 ACPI: Battery: Ad... |
254 255 256 |
break; case POWER_SUPPLY_PROP_CHARGE_NOW: case POWER_SUPPLY_PROP_ENERGY_NOW: |
a1b4bd694 ACPI / Battery: R... |
257 258 259 260 |
if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN) ret = -ENODEV; else val->intval = battery->capacity_now * 1000; |
d73809657 ACPI: Battery: Ad... |
261 |
break; |
a58e11502 ACPI Battery: Add... |
262 |
case POWER_SUPPLY_PROP_CAPACITY: |
5b74d1d16 ACPI / battery: U... |
263 264 265 266 |
if (ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity)) full_capacity = battery->full_charge_capacity; else if (ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity)) full_capacity = battery->design_capacity; |
cc99f0ad5 ACPI / battery: D... |
267 |
if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN || |
5b74d1d16 ACPI / battery: U... |
268 |
full_capacity == ACPI_BATTERY_VALUE_UNKNOWN) |
cc99f0ad5 ACPI / battery: D... |
269 270 |
ret = -ENODEV; else |
a58e11502 ACPI Battery: Add... |
271 |
val->intval = battery->capacity_now * 100/ |
5b74d1d16 ACPI / battery: U... |
272 |
full_capacity; |
a58e11502 ACPI Battery: Add... |
273 |
break; |
1ac5aaa67 ACPI / battery: i... |
274 275 276 277 278 279 280 281 282 283 284 |
case POWER_SUPPLY_PROP_CAPACITY_LEVEL: if (battery->state & ACPI_BATTERY_STATE_CRITICAL) val->intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL; else if (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) && (battery->capacity_now <= battery->alarm)) val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW; else if (acpi_battery_is_charged(battery)) val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL; else val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; break; |
d73809657 ACPI: Battery: Ad... |
285 286 287 288 289 290 |
case POWER_SUPPLY_PROP_MODEL_NAME: val->strval = battery->model_number; break; case POWER_SUPPLY_PROP_MANUFACTURER: val->strval = battery->oem_info; break; |
7c2670bbb ACPI: battery: ad... |
291 292 293 |
case POWER_SUPPLY_PROP_SERIAL_NUMBER: val->strval = battery->serial_number; break; |
d73809657 ACPI: Battery: Ad... |
294 |
default: |
a1b4bd694 ACPI / Battery: R... |
295 |
ret = -EINVAL; |
d73809657 ACPI: Battery: Ad... |
296 |
} |
a1b4bd694 ACPI / Battery: R... |
297 |
return ret; |
d73809657 ACPI: Battery: Ad... |
298 299 300 301 302 303 |
} static enum power_supply_property charge_battery_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_TECHNOLOGY, |
c67fcd670 ACPI: Battery: Ad... |
304 |
POWER_SUPPLY_PROP_CYCLE_COUNT, |
d73809657 ACPI: Battery: Ad... |
305 306 307 308 309 310 |
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, POWER_SUPPLY_PROP_CHARGE_FULL, POWER_SUPPLY_PROP_CHARGE_NOW, |
a58e11502 ACPI Battery: Add... |
311 |
POWER_SUPPLY_PROP_CAPACITY, |
1ac5aaa67 ACPI / battery: i... |
312 |
POWER_SUPPLY_PROP_CAPACITY_LEVEL, |
d73809657 ACPI: Battery: Ad... |
313 314 |
POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_MANUFACTURER, |
7c2670bbb ACPI: battery: ad... |
315 |
POWER_SUPPLY_PROP_SERIAL_NUMBER, |
d73809657 ACPI: Battery: Ad... |
316 |
}; |
ff3154d1d ACPI / battery: D... |
317 318 319 320 321 322 323 324 325 326 327 328 329 |
static enum power_supply_property charge_battery_full_cap_broken_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_TECHNOLOGY, POWER_SUPPLY_PROP_CYCLE_COUNT, POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_CHARGE_NOW, POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_MANUFACTURER, POWER_SUPPLY_PROP_SERIAL_NUMBER, }; |
d73809657 ACPI: Battery: Ad... |
330 331 332 333 |
static enum power_supply_property energy_battery_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_TECHNOLOGY, |
c67fcd670 ACPI: Battery: Ad... |
334 |
POWER_SUPPLY_PROP_CYCLE_COUNT, |
d73809657 ACPI: Battery: Ad... |
335 336 |
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, POWER_SUPPLY_PROP_VOLTAGE_NOW, |
7faa144a5 ACPI: battery: ad... |
337 |
POWER_SUPPLY_PROP_POWER_NOW, |
d73809657 ACPI: Battery: Ad... |
338 339 340 |
POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, POWER_SUPPLY_PROP_ENERGY_FULL, POWER_SUPPLY_PROP_ENERGY_NOW, |
a58e11502 ACPI Battery: Add... |
341 |
POWER_SUPPLY_PROP_CAPACITY, |
1ac5aaa67 ACPI / battery: i... |
342 |
POWER_SUPPLY_PROP_CAPACITY_LEVEL, |
d73809657 ACPI: Battery: Ad... |
343 344 |
POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_MANUFACTURER, |
7c2670bbb ACPI: battery: ad... |
345 |
POWER_SUPPLY_PROP_SERIAL_NUMBER, |
d73809657 ACPI: Battery: Ad... |
346 |
}; |
b41901a2c ACPI / battery: D... |
347 348 349 350 351 352 353 354 355 356 357 358 359 |
static enum power_supply_property energy_battery_full_cap_broken_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_TECHNOLOGY, POWER_SUPPLY_PROP_CYCLE_COUNT, POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_POWER_NOW, POWER_SUPPLY_PROP_ENERGY_NOW, POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_MANUFACTURER, POWER_SUPPLY_PROP_SERIAL_NUMBER, }; |
78490d821 ACPI: battery: sy... |
360 361 362 |
/* -------------------------------------------------------------------------- Battery Management -------------------------------------------------------------------------- */ |
038fdea29 ACPI: Battery: do... |
363 364 365 366 |
struct acpi_offsets { size_t offset; /* offset inside struct acpi_sbs_battery */ u8 mode; /* int or string? */ }; |
b6ce4083e ACPI: Cache batte... |
367 |
|
a46587845 ACPI / battery: c... |
368 |
static const struct acpi_offsets state_offsets[] = { |
038fdea29 ACPI: Battery: do... |
369 |
{offsetof(struct acpi_battery, state), 0}, |
7faa144a5 ACPI: battery: ad... |
370 |
{offsetof(struct acpi_battery, rate_now), 0}, |
d73809657 ACPI: Battery: Ad... |
371 372 |
{offsetof(struct acpi_battery, capacity_now), 0}, {offsetof(struct acpi_battery, voltage_now), 0}, |
038fdea29 ACPI: Battery: do... |
373 |
}; |
b6ce4083e ACPI: Cache batte... |
374 |
|
a46587845 ACPI / battery: c... |
375 |
static const struct acpi_offsets info_offsets[] = { |
038fdea29 ACPI: Battery: do... |
376 377 |
{offsetof(struct acpi_battery, power_unit), 0}, {offsetof(struct acpi_battery, design_capacity), 0}, |
d73809657 ACPI: Battery: Ad... |
378 |
{offsetof(struct acpi_battery, full_charge_capacity), 0}, |
038fdea29 ACPI: Battery: do... |
379 380 381 382 383 384 385 386 387 388 389 |
{offsetof(struct acpi_battery, technology), 0}, {offsetof(struct acpi_battery, design_voltage), 0}, {offsetof(struct acpi_battery, design_capacity_warning), 0}, {offsetof(struct acpi_battery, design_capacity_low), 0}, {offsetof(struct acpi_battery, capacity_granularity_1), 0}, {offsetof(struct acpi_battery, capacity_granularity_2), 0}, {offsetof(struct acpi_battery, model_number), 1}, {offsetof(struct acpi_battery, serial_number), 1}, {offsetof(struct acpi_battery, type), 1}, {offsetof(struct acpi_battery, oem_info), 1}, }; |
b6ce4083e ACPI: Cache batte... |
390 |
|
a46587845 ACPI / battery: c... |
391 |
static const struct acpi_offsets extended_info_offsets[] = { |
016d5baad ACPI / battery: F... |
392 |
{offsetof(struct acpi_battery, revision), 0}, |
c67fcd670 ACPI: Battery: Ad... |
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 |
{offsetof(struct acpi_battery, power_unit), 0}, {offsetof(struct acpi_battery, design_capacity), 0}, {offsetof(struct acpi_battery, full_charge_capacity), 0}, {offsetof(struct acpi_battery, technology), 0}, {offsetof(struct acpi_battery, design_voltage), 0}, {offsetof(struct acpi_battery, design_capacity_warning), 0}, {offsetof(struct acpi_battery, design_capacity_low), 0}, {offsetof(struct acpi_battery, cycle_count), 0}, {offsetof(struct acpi_battery, measurement_accuracy), 0}, {offsetof(struct acpi_battery, max_sampling_time), 0}, {offsetof(struct acpi_battery, min_sampling_time), 0}, {offsetof(struct acpi_battery, max_averaging_interval), 0}, {offsetof(struct acpi_battery, min_averaging_interval), 0}, {offsetof(struct acpi_battery, capacity_granularity_1), 0}, {offsetof(struct acpi_battery, capacity_granularity_2), 0}, {offsetof(struct acpi_battery, model_number), 1}, {offsetof(struct acpi_battery, serial_number), 1}, {offsetof(struct acpi_battery, type), 1}, {offsetof(struct acpi_battery, oem_info), 1}, }; |
038fdea29 ACPI: Battery: do... |
413 414 |
static int extract_package(struct acpi_battery *battery, union acpi_object *package, |
a46587845 ACPI / battery: c... |
415 |
const struct acpi_offsets *offsets, int num) |
038fdea29 ACPI: Battery: do... |
416 |
{ |
106449e87 ACPI: Battery: Al... |
417 |
int i; |
038fdea29 ACPI: Battery: do... |
418 419 420 421 422 423 424 425 |
union acpi_object *element; if (package->type != ACPI_TYPE_PACKAGE) return -EFAULT; for (i = 0; i < num; ++i) { if (package->package.count <= i) return -EFAULT; element = &package->package.elements[i]; if (offsets[i].mode) { |
106449e87 ACPI: Battery: Al... |
426 427 428 429 430 431 |
u8 *ptr = (u8 *)battery + offsets[i].offset; if (element->type == ACPI_TYPE_STRING || element->type == ACPI_TYPE_BUFFER) strncpy(ptr, element->string.pointer, 32); else if (element->type == ACPI_TYPE_INTEGER) { strncpy(ptr, (u8 *)&element->integer.value, |
439913fff ACPI: replace acp... |
432 433 |
sizeof(u64)); ptr[sizeof(u64)] = 0; |
b8a1bdb14 ACPI: battery: Do... |
434 435 |
} else *ptr = 0; /* don't have value */ |
038fdea29 ACPI: Battery: do... |
436 |
} else { |
b8a1bdb14 ACPI: battery: Do... |
437 438 439 |
int *x = (int *)((u8 *)battery + offsets[i].offset); *x = (element->type == ACPI_TYPE_INTEGER) ? element->integer.value : -1; |
038fdea29 ACPI: Battery: do... |
440 |
} |
b6ce4083e ACPI: Cache batte... |
441 |
} |
b6ce4083e ACPI: Cache batte... |
442 443 444 445 446 |
return 0; } static int acpi_battery_get_status(struct acpi_battery *battery) { |
aa650bbdc ACPI: Battery: Mi... |
447 |
if (acpi_bus_get_status(battery->device)) { |
b6ce4083e ACPI: Cache batte... |
448 449 450 |
ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA")); return -ENODEV; } |
aa650bbdc ACPI: Battery: Mi... |
451 |
return 0; |
b6ce4083e ACPI: Cache batte... |
452 |
} |
2d09af4a8 ACPI / battery: I... |
453 454 455 456 |
static int extract_battery_info(const int use_bix, struct acpi_battery *battery, const struct acpi_buffer *buffer) |
1da177e4c Linux-2.6.12-rc2 |
457 |
{ |
aa650bbdc ACPI: Battery: Mi... |
458 |
int result = -EFAULT; |
1da177e4c Linux-2.6.12-rc2 |
459 |
|
2d09af4a8 ACPI / battery: I... |
460 461 |
if (use_bix && battery_bix_broken_package) result = extract_package(battery, buffer->pointer, |
a90b40385 ACPI / Battery: A... |
462 463 |
extended_info_offsets + 1, ARRAY_SIZE(extended_info_offsets) - 1); |
2d09af4a8 ACPI / battery: I... |
464 465 |
else if (use_bix) result = extract_package(battery, buffer->pointer, |
c67fcd670 ACPI: Battery: Ad... |
466 467 468 |
extended_info_offsets, ARRAY_SIZE(extended_info_offsets)); else |
2d09af4a8 ACPI / battery: I... |
469 |
result = extract_package(battery, buffer->pointer, |
c67fcd670 ACPI: Battery: Ad... |
470 |
info_offsets, ARRAY_SIZE(info_offsets)); |
557d58687 ACPI battery: sup... |
471 472 |
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)) battery->full_charge_capacity = battery->design_capacity; |
4000e6261 ACPI / battery: C... |
473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 |
if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) && battery->power_unit && battery->design_voltage) { battery->design_capacity = battery->design_capacity * 10000 / battery->design_voltage; battery->full_charge_capacity = battery->full_charge_capacity * 10000 / battery->design_voltage; battery->design_capacity_warning = battery->design_capacity_warning * 10000 / battery->design_voltage; /* Curiously, design_capacity_low, unlike the rest of them, is correct. */ /* capacity_granularity_* equal 1 on the systems tested, so it's impossible to tell if they would need an adjustment or not if their values were higher. */ } |
a20136a67 ACPI: battery: do... |
488 489 490 |
if (test_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags) && battery->capacity_now > battery->full_charge_capacity) battery->capacity_now = battery->full_charge_capacity; |
d550d98d3 ACPI: delete trac... |
491 |
return result; |
1da177e4c Linux-2.6.12-rc2 |
492 |
} |
2d09af4a8 ACPI / battery: I... |
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 |
static int acpi_battery_get_info(struct acpi_battery *battery) { const int xinfo = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); int use_bix; int result = -ENODEV; if (!acpi_battery_present(battery)) return 0; for (use_bix = xinfo ? 1 : 0; use_bix >= 0; use_bix--) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; acpi_status status = AE_ERROR; mutex_lock(&battery->lock); status = acpi_evaluate_object(battery->device->handle, use_bix ? "_BIX":"_BIF", NULL, &buffer); mutex_unlock(&battery->lock); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s", use_bix ? "_BIX":"_BIF")); } else { result = extract_battery_info(use_bix, battery, &buffer); kfree(buffer.pointer); break; } } if (!result && !use_bix && xinfo) pr_warn(FW_BUG "The _BIX method is broken, using _BIF. "); return result; } |
b6ce4083e ACPI: Cache batte... |
532 |
static int acpi_battery_get_state(struct acpi_battery *battery) |
1da177e4c Linux-2.6.12-rc2 |
533 |
{ |
4be44fcd3 [ACPI] Lindent al... |
534 535 536 |
int result = 0; acpi_status status = 0; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
1da177e4c Linux-2.6.12-rc2 |
537 |
|
b6ce4083e ACPI: Cache batte... |
538 539 |
if (!acpi_battery_present(battery)) return 0; |
1da177e4c Linux-2.6.12-rc2 |
540 |
|
f1d4661ab ACPI: Battery: si... |
541 542 543 544 |
if (battery->update_time && time_before(jiffies, battery->update_time + msecs_to_jiffies(cache_time))) return 0; |
038fdea29 ACPI: Battery: do... |
545 |
mutex_lock(&battery->lock); |
f1d4661ab ACPI: Battery: si... |
546 |
status = acpi_evaluate_object(battery->device->handle, "_BST", |
038fdea29 ACPI: Battery: do... |
547 548 |
NULL, &buffer); mutex_unlock(&battery->lock); |
5b31d8958 Revert "ACPI: Bat... |
549 |
|
1da177e4c Linux-2.6.12-rc2 |
550 |
if (ACPI_FAILURE(status)) { |
a6fc67202 ACPI: Enable ACPI... |
551 |
ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); |
d550d98d3 ACPI: delete trac... |
552 |
return -ENODEV; |
1da177e4c Linux-2.6.12-rc2 |
553 |
} |
aa650bbdc ACPI: Battery: Mi... |
554 |
|
038fdea29 ACPI: Battery: do... |
555 556 |
result = extract_package(battery, buffer.pointer, state_offsets, ARRAY_SIZE(state_offsets)); |
f1d4661ab ACPI: Battery: si... |
557 |
battery->update_time = jiffies; |
78490d821 ACPI: battery: sy... |
558 |
kfree(buffer.pointer); |
bc76f90b8 ACPI battery: wor... |
559 |
|
55003b210 ACPI / Battery: C... |
560 561 562 563 564 565 566 |
/* For buggy DSDTs that report negative 16-bit values for either * charging or discharging current and/or report 0 as 65536 * due to bad math. */ if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA && battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN && (s16)(battery->rate_now) < 0) { |
bc76f90b8 ACPI battery: wor... |
567 |
battery->rate_now = abs((s16)battery->rate_now); |
dd1fca9e6 ACPI / battery: u... |
568 569 |
pr_warn_once(FW_BUG "battery: (dis)charge rate invalid. "); |
55003b210 ACPI / Battery: C... |
570 |
} |
bc76f90b8 ACPI battery: wor... |
571 |
|
557d58687 ACPI battery: sup... |
572 573 574 575 |
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags) && battery->capacity_now >= 0 && battery->capacity_now <= 100) battery->capacity_now = (battery->capacity_now * battery->full_charge_capacity) / 100; |
4000e6261 ACPI / battery: C... |
576 577 578 579 580 |
if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) && battery->power_unit && battery->design_voltage) { battery->capacity_now = battery->capacity_now * 10000 / battery->design_voltage; } |
a20136a67 ACPI: battery: do... |
581 582 583 |
if (test_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags) && battery->capacity_now > battery->full_charge_capacity) battery->capacity_now = battery->full_charge_capacity; |
b6ce4083e ACPI: Cache batte... |
584 585 |
return result; } |
1da177e4c Linux-2.6.12-rc2 |
586 |
|
aa650bbdc ACPI: Battery: Mi... |
587 |
static int acpi_battery_set_alarm(struct acpi_battery *battery) |
1da177e4c Linux-2.6.12-rc2 |
588 |
{ |
4be44fcd3 [ACPI] Lindent al... |
589 |
acpi_status status = 0; |
1da177e4c Linux-2.6.12-rc2 |
590 |
|
c67fcd670 ACPI: Battery: Ad... |
591 |
if (!acpi_battery_present(battery) || |
7b3bcc4a1 ACPI: Battery: Ad... |
592 |
!test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags)) |
d550d98d3 ACPI: delete trac... |
593 |
return -ENODEV; |
1da177e4c Linux-2.6.12-rc2 |
594 |
|
038fdea29 ACPI: Battery: do... |
595 |
mutex_lock(&battery->lock); |
0db982026 ACPI: introduce h... |
596 597 |
status = acpi_execute_simple_method(battery->device->handle, "_BTP", battery->alarm); |
038fdea29 ACPI: Battery: do... |
598 |
mutex_unlock(&battery->lock); |
aa650bbdc ACPI: Battery: Mi... |
599 |
|
1da177e4c Linux-2.6.12-rc2 |
600 |
if (ACPI_FAILURE(status)) |
d550d98d3 ACPI: delete trac... |
601 |
return -ENODEV; |
1da177e4c Linux-2.6.12-rc2 |
602 |
|
aa650bbdc ACPI: Battery: Mi... |
603 604 |
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d ", battery->alarm)); |
d550d98d3 ACPI: delete trac... |
605 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
606 |
} |
b6ce4083e ACPI: Cache batte... |
607 |
static int acpi_battery_init_alarm(struct acpi_battery *battery) |
1da177e4c Linux-2.6.12-rc2 |
608 |
{ |
b6ce4083e ACPI: Cache batte... |
609 |
/* See if alarms are supported, and if so, set default */ |
952c63e95 ACPI: introduce h... |
610 |
if (!acpi_has_method(battery->device->handle, "_BTP")) { |
7b3bcc4a1 ACPI: Battery: Ad... |
611 |
clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags); |
f1d4661ab ACPI: Battery: si... |
612 |
return 0; |
b6ce4083e ACPI: Cache batte... |
613 |
} |
7b3bcc4a1 ACPI: Battery: Ad... |
614 |
set_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags); |
f1d4661ab ACPI: Battery: si... |
615 616 |
if (!battery->alarm) battery->alarm = battery->design_capacity_warning; |
aa650bbdc ACPI: Battery: Mi... |
617 |
return acpi_battery_set_alarm(battery); |
b6ce4083e ACPI: Cache batte... |
618 |
} |
1da177e4c Linux-2.6.12-rc2 |
619 |
|
508df92d1 ACPI: battery: re... |
620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 |
static ssize_t acpi_battery_alarm_show(struct device *dev, struct device_attribute *attr, char *buf) { struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev)); return sprintf(buf, "%d ", battery->alarm * 1000); } static ssize_t acpi_battery_alarm_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long x; struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev)); |
47a08c85f ACPI / battery: F... |
635 636 |
if (sscanf(buf, "%lu ", &x) == 1) |
508df92d1 ACPI: battery: re... |
637 638 639 640 641 |
battery->alarm = x/1000; if (acpi_battery_present(battery)) acpi_battery_set_alarm(battery); return count; } |
82d2b6105 ACPI: make device... |
642 |
static const struct device_attribute alarm_attr = { |
01e8ef11b x86: sysfs: kill ... |
643 |
.attr = {.name = "alarm", .mode = 0644}, |
508df92d1 ACPI: battery: re... |
644 645 646 |
.show = acpi_battery_alarm_show, .store = acpi_battery_alarm_store, }; |
fa93854f7 battery: Add the ... |
647 648 649 650 651 652 653 654 655 656 657 658 |
/* * The Battery Hooking API * * This API is used inside other drivers that need to expose * platform-specific behaviour within the generic driver in a * generic way. * */ static LIST_HEAD(acpi_battery_list); static LIST_HEAD(battery_hook_list); static DEFINE_MUTEX(hook_mutex); |
514bcc5df ACPI: battery: ma... |
659 |
static void __battery_hook_unregister(struct acpi_battery_hook *hook, int lock) |
fa93854f7 battery: Add the ... |
660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 |
{ struct acpi_battery *battery; /* * In order to remove a hook, we first need to * de-register all the batteries that are registered. */ if (lock) mutex_lock(&hook_mutex); list_for_each_entry(battery, &acpi_battery_list, list) { hook->remove_battery(battery->bat); } list_del(&hook->list); if (lock) mutex_unlock(&hook_mutex); pr_info("extension unregistered: %s ", hook->name); } void battery_hook_unregister(struct acpi_battery_hook *hook) { __battery_hook_unregister(hook, 1); } EXPORT_SYMBOL_GPL(battery_hook_unregister); void battery_hook_register(struct acpi_battery_hook *hook) { struct acpi_battery *battery; mutex_lock(&hook_mutex); INIT_LIST_HEAD(&hook->list); list_add(&hook->list, &battery_hook_list); /* * Now that the driver is registered, we need * to notify the hook that a battery is available * for each battery, so that the driver may add * its attributes. */ list_for_each_entry(battery, &acpi_battery_list, list) { if (hook->add_battery(battery->bat)) { /* * If a add-battery returns non-zero, * the registration of the extension has failed, * and we will not add it to the list of loaded * hooks. */ pr_err("extension failed to load: %s", hook->name); __battery_hook_unregister(hook, 0); |
673b42716 ACPI / battery: S... |
707 |
goto end; |
fa93854f7 battery: Add the ... |
708 709 710 711 |
} } pr_info("new extension: %s ", hook->name); |
673b42716 ACPI / battery: S... |
712 |
end: |
fa93854f7 battery: Add the ... |
713 714 715 716 717 718 719 720 |
mutex_unlock(&hook_mutex); } EXPORT_SYMBOL_GPL(battery_hook_register); /* * This function gets called right after the battery sysfs * attributes have been added, so that the drivers that * define custom sysfs attributes can add their own. |
7a4ea10c0 Revert "ACPI: bat... |
721 |
*/ |
fa93854f7 battery: Add the ... |
722 723 |
static void battery_hook_add_battery(struct acpi_battery *battery) { |
673b42716 ACPI / battery: S... |
724 |
struct acpi_battery_hook *hook_node, *tmp; |
fa93854f7 battery: Add the ... |
725 726 727 728 729 730 731 732 733 734 735 |
mutex_lock(&hook_mutex); INIT_LIST_HEAD(&battery->list); list_add(&battery->list, &acpi_battery_list); /* * Since we added a new battery to the list, we need to * iterate over the hooks and call add_battery for each * hook that was registered. This usually happens * when a battery gets hotplugged or initialized * during the battery module initialization. */ |
673b42716 ACPI / battery: S... |
736 |
list_for_each_entry_safe(hook_node, tmp, &battery_hook_list, list) { |
fa93854f7 battery: Add the ... |
737 738 739 740 741 |
if (hook_node->add_battery(battery->bat)) { /* * The notification of the extensions has failed, to * prevent further errors we will unload the extension. */ |
fa93854f7 battery: Add the ... |
742 743 |
pr_err("error in extension, unloading: %s", hook_node->name); |
673b42716 ACPI / battery: S... |
744 |
__battery_hook_unregister(hook_node, 0); |
fa93854f7 battery: Add the ... |
745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 |
} } mutex_unlock(&hook_mutex); } static void battery_hook_remove_battery(struct acpi_battery *battery) { struct acpi_battery_hook *hook; mutex_lock(&hook_mutex); /* * Before removing the hook, we need to remove all * custom attributes from the battery. */ list_for_each_entry(hook, &battery_hook_list, list) { hook->remove_battery(battery->bat); } /* Then, just remove the battery from the list */ list_del(&battery->list); mutex_unlock(&hook_mutex); } static void __exit battery_hook_exit(void) { struct acpi_battery_hook *hook; struct acpi_battery_hook *ptr; /* * At this point, the acpi_bus_unregister_driver() * has called remove for all batteries. We just * need to remove the hooks. */ list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) { __battery_hook_unregister(hook, 1); } mutex_destroy(&hook_mutex); } |
508df92d1 ACPI: battery: re... |
781 782 |
static int sysfs_add_battery(struct acpi_battery *battery) { |
297d716f6 power_supply: Cha... |
783 |
struct power_supply_config psy_cfg = { .drv_data = battery, }; |
ff3154d1d ACPI / battery: D... |
784 785 786 787 788 |
bool full_cap_broken = false; if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) && !ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity)) full_cap_broken = true; |
508df92d1 ACPI: battery: re... |
789 |
|
ae6f61870 ACPI / Battery: A... |
790 |
if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) { |
ff3154d1d ACPI / battery: D... |
791 792 793 794 795 796 797 798 799 800 |
if (full_cap_broken) { battery->bat_desc.properties = charge_battery_full_cap_broken_props; battery->bat_desc.num_properties = ARRAY_SIZE(charge_battery_full_cap_broken_props); } else { battery->bat_desc.properties = charge_battery_props; battery->bat_desc.num_properties = ARRAY_SIZE(charge_battery_props); } |
508df92d1 ACPI: battery: re... |
801 |
} else { |
ff3154d1d ACPI / battery: D... |
802 803 804 805 806 807 808 809 810 811 |
if (full_cap_broken) { battery->bat_desc.properties = energy_battery_full_cap_broken_props; battery->bat_desc.num_properties = ARRAY_SIZE(energy_battery_full_cap_broken_props); } else { battery->bat_desc.properties = energy_battery_props; battery->bat_desc.num_properties = ARRAY_SIZE(energy_battery_props); } |
508df92d1 ACPI: battery: re... |
812 |
} |
297d716f6 power_supply: Cha... |
813 814 815 |
battery->bat_desc.name = acpi_device_bid(battery->device); battery->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY; battery->bat_desc.get_property = acpi_battery_get_property; |
508df92d1 ACPI: battery: re... |
816 |
|
297d716f6 power_supply: Cha... |
817 818 |
battery->bat = power_supply_register_no_ws(&battery->device->dev, &battery->bat_desc, &psy_cfg); |
e0d1f09e3 ACPI / battery: w... |
819 |
|
297d716f6 power_supply: Cha... |
820 821 822 823 |
if (IS_ERR(battery->bat)) { int result = PTR_ERR(battery->bat); battery->bat = NULL; |
508df92d1 ACPI: battery: re... |
824 |
return result; |
297d716f6 power_supply: Cha... |
825 |
} |
fa93854f7 battery: Add the ... |
826 |
battery_hook_add_battery(battery); |
297d716f6 power_supply: Cha... |
827 |
return device_create_file(&battery->bat->dev, &alarm_attr); |
508df92d1 ACPI: battery: re... |
828 829 830 831 |
} static void sysfs_remove_battery(struct acpi_battery *battery) { |
69d94ec6d Battery: sysfs_re... |
832 |
mutex_lock(&battery->sysfs_lock); |
297d716f6 power_supply: Cha... |
833 |
if (!battery->bat) { |
69d94ec6d Battery: sysfs_re... |
834 |
mutex_unlock(&battery->sysfs_lock); |
508df92d1 ACPI: battery: re... |
835 |
return; |
9c921c22a ACPI / Battery: R... |
836 |
} |
fa93854f7 battery: Add the ... |
837 |
battery_hook_remove_battery(battery); |
297d716f6 power_supply: Cha... |
838 839 840 |
device_remove_file(&battery->bat->dev, &alarm_attr); power_supply_unregister(battery->bat); battery->bat = NULL; |
69d94ec6d Battery: sysfs_re... |
841 |
mutex_unlock(&battery->sysfs_lock); |
bc76f90b8 ACPI battery: wor... |
842 |
} |
4000e6261 ACPI / battery: C... |
843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 |
static void find_battery(const struct dmi_header *dm, void *private) { struct acpi_battery *battery = (struct acpi_battery *)private; /* Note: the hardcoded offsets below have been extracted from the source code of dmidecode. */ if (dm->type == DMI_ENTRY_PORTABLE_BATTERY && dm->length >= 8) { const u8 *dmi_data = (const u8 *)(dm + 1); int dmi_capacity = get_unaligned((const u16 *)(dmi_data + 6)); if (dm->length >= 18) dmi_capacity *= dmi_data[17]; if (battery->design_capacity * battery->design_voltage / 1000 != dmi_capacity && battery->design_capacity * 10 == dmi_capacity) set_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags); } } |
557d58687 ACPI battery: sup... |
860 861 862 863 864 865 866 867 868 869 870 871 |
/* * According to the ACPI spec, some kinds of primary batteries can * report percentage battery remaining capacity directly to OS. * In this case, it reports the Last Full Charged Capacity == 100 * and BatteryPresentRate == 0xFFFFFFFF. * * Now we found some battery reports percentage remaining capacity * even if it's rechargeable. * https://bugzilla.kernel.org/show_bug.cgi?id=15979 * * Handle this correctly so that they won't break userspace. */ |
7b78622d0 ACPI / Battery: R... |
872 |
static void acpi_battery_quirks(struct acpi_battery *battery) |
557d58687 ACPI battery: sup... |
873 874 |
{ if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)) |
0f4c65478 ACPI / battery: M... |
875 |
return; |
557d58687 ACPI battery: sup... |
876 |
|
0f4c65478 ACPI / battery: M... |
877 878 879 |
if (battery->full_charge_capacity == 100 && battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN && battery->capacity_now >= 0 && battery->capacity_now <= 100) { |
557d58687 ACPI battery: sup... |
880 881 882 883 884 |
set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags); battery->full_charge_capacity = battery->design_capacity; battery->capacity_now = (battery->capacity_now * battery->full_charge_capacity) / 100; } |
4000e6261 ACPI / battery: C... |
885 886 |
if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags)) |
0f4c65478 ACPI / battery: M... |
887 |
return; |
4000e6261 ACPI / battery: C... |
888 889 890 891 |
if (battery->power_unit && dmi_name_in_vendors("LENOVO")) { const char *s; s = dmi_get_system_info(DMI_PRODUCT_VERSION); |
ffd8a731d ACPI / battery: R... |
892 |
if (s && !strncasecmp(s, "ThinkPad", 8)) { |
4000e6261 ACPI / battery: C... |
893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 |
dmi_walk(find_battery, battery); if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) && battery->design_voltage) { battery->design_capacity = battery->design_capacity * 10000 / battery->design_voltage; battery->full_charge_capacity = battery->full_charge_capacity * 10000 / battery->design_voltage; battery->design_capacity_warning = battery->design_capacity_warning * 10000 / battery->design_voltage; battery->capacity_now = battery->capacity_now * 10000 / battery->design_voltage; } } } |
a20136a67 ACPI: battery: do... |
911 912 913 914 915 916 917 918 919 |
if (test_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags)) return; if (acpi_battery_is_degraded(battery) && battery->capacity_now > battery->full_charge_capacity) { set_bit(ACPI_BATTERY_QUIRK_DEGRADED_FULL_CHARGE, &battery->flags); battery->capacity_now = battery->full_charge_capacity; } |
557d58687 ACPI battery: sup... |
920 |
} |
9e50bc14a ACPI / battery: A... |
921 |
static int acpi_battery_update(struct acpi_battery *battery, bool resume) |
b6ce4083e ACPI: Cache batte... |
922 |
{ |
82f2d3057 ACPI: battery: re... |
923 |
int result = acpi_battery_get_status(battery); |
508df92d1 ACPI: battery: re... |
924 |
if (result) |
b6ce4083e ACPI: Cache batte... |
925 |
return result; |
82f2d3057 ACPI: battery: re... |
926 |
|
508df92d1 ACPI: battery: re... |
927 928 |
if (!acpi_battery_present(battery)) { sysfs_remove_battery(battery); |
97749cd9a ACPI: Make sysfs ... |
929 |
battery->update_time = 0; |
508df92d1 ACPI: battery: re... |
930 |
return 0; |
b6ce4083e ACPI: Cache batte... |
931 |
} |
9e50bc14a ACPI / battery: A... |
932 933 934 |
if (resume) return 0; |
82f2d3057 ACPI: battery: re... |
935 |
if (!battery->update_time) { |
97749cd9a ACPI: Make sysfs ... |
936 937 938 939 940 |
result = acpi_battery_get_info(battery); if (result) return result; acpi_battery_init_alarm(battery); } |
12c78ca2a ACPI / battery: A... |
941 942 943 944 945 |
result = acpi_battery_get_state(battery); if (result) return result; acpi_battery_quirks(battery); |
297d716f6 power_supply: Cha... |
946 |
if (!battery->bat) { |
eb03cb02b ACPI / Battery: p... |
947 948 949 950 |
result = sysfs_add_battery(battery); if (result) return result; } |
e0d1f09e3 ACPI / battery: w... |
951 952 953 954 955 956 957 |
/* * Wakeup the system if battery is critical low * or lower than the alarm level */ if ((battery->state & ACPI_BATTERY_STATE_CRITICAL) || (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) && |
c6237b210 ACPI: Fix whitesp... |
958 |
(battery->capacity_now <= battery->alarm))) |
33e4f80ee ACPI / PM: Ignore... |
959 |
acpi_pm_wakeup_event(&battery->device->dev); |
e0d1f09e3 ACPI / battery: w... |
960 |
|
557d58687 ACPI battery: sup... |
961 |
return result; |
4bd35cdb1 ACPI: battery: ch... |
962 |
} |
da8aeb92d ACPI / Battery: U... |
963 964 |
static void acpi_battery_refresh(struct acpi_battery *battery) { |
c59714569 ACPI battery: onl... |
965 |
int power_unit; |
297d716f6 power_supply: Cha... |
966 |
if (!battery->bat) |
da8aeb92d ACPI / Battery: U... |
967 |
return; |
c59714569 ACPI battery: onl... |
968 |
power_unit = battery->power_unit; |
da8aeb92d ACPI / Battery: U... |
969 |
acpi_battery_get_info(battery); |
c59714569 ACPI battery: onl... |
970 971 972 973 974 |
if (power_unit == battery->power_unit) return; /* The battery has changed its reporting units. */ |
da8aeb92d ACPI / Battery: U... |
975 976 977 |
sysfs_remove_battery(battery); sysfs_add_battery(battery); } |
1da177e4c Linux-2.6.12-rc2 |
978 |
/* -------------------------------------------------------------------------- |
1da177e4c Linux-2.6.12-rc2 |
979 980 |
Driver Interface -------------------------------------------------------------------------- */ |
d94066910 ACPI: battery: us... |
981 |
static void acpi_battery_notify(struct acpi_device *device, u32 event) |
1da177e4c Linux-2.6.12-rc2 |
982 |
{ |
d94066910 ACPI: battery: us... |
983 |
struct acpi_battery *battery = acpi_driver_data(device); |
297d716f6 power_supply: Cha... |
984 |
struct power_supply *old; |
d94066910 ACPI: battery: us... |
985 |
|
1da177e4c Linux-2.6.12-rc2 |
986 |
if (!battery) |
d550d98d3 ACPI: delete trac... |
987 |
return; |
297d716f6 power_supply: Cha... |
988 |
old = battery->bat; |
f43691c61 ACPI / battery: a... |
989 990 991 992 993 994 995 996 |
/* * On Acer Aspire V5-573G notifications are sometimes triggered too * early. For example, when AC is unplugged and notification is * triggered, battery state is still reported as "Full", and changes to * "Discharging" only after short delay, without any notification. */ if (battery_notification_delay_ms > 0) msleep(battery_notification_delay_ms); |
da8aeb92d ACPI / Battery: U... |
997 998 |
if (event == ACPI_BATTERY_NOTIFY_INFO) acpi_battery_refresh(battery); |
9e50bc14a ACPI / battery: A... |
999 |
acpi_battery_update(battery, false); |
f1d4661ab ACPI: Battery: si... |
1000 |
acpi_bus_generate_netlink_event(device->pnp.device_class, |
0794469da ACPI: struct devi... |
1001 |
dev_name(&device->dev), event, |
9ea7d5757 ACPI: battery: Li... |
1002 |
acpi_battery_present(battery)); |
411e0f77b ACPI / battery: c... |
1003 |
acpi_notifier_call_chain(device, event, acpi_battery_present(battery)); |
2345baf4a battery: fix typo... |
1004 |
/* acpi_battery_update could remove power_supply object */ |
297d716f6 power_supply: Cha... |
1005 1006 |
if (old && battery->bat) power_supply_changed(battery->bat); |
1da177e4c Linux-2.6.12-rc2 |
1007 |
} |
25be58215 ACPI battery: fri... |
1008 1009 1010 1011 1012 |
static int battery_notify(struct notifier_block *nb, unsigned long mode, void *_unused) { struct acpi_battery *battery = container_of(nb, struct acpi_battery, pm_nb); |
9e50bc14a ACPI / battery: A... |
1013 |
int result; |
25be58215 ACPI battery: fri... |
1014 |
switch (mode) { |
d5a5911b3 ACPI / Battery: A... |
1015 |
case PM_POST_HIBERNATION: |
25be58215 ACPI battery: fri... |
1016 |
case PM_POST_SUSPEND: |
9e50bc14a ACPI / battery: A... |
1017 1018 |
if (!acpi_battery_present(battery)) return 0; |
2754435d4 ACPI / battery: g... |
1019 1020 1021 |
if (battery->bat) { acpi_battery_refresh(battery); } else { |
9e50bc14a ACPI / battery: A... |
1022 1023 1024 1025 1026 1027 1028 |
result = acpi_battery_get_info(battery); if (result) return result; result = sysfs_add_battery(battery); if (result) return result; |
2754435d4 ACPI / battery: g... |
1029 |
} |
9e50bc14a ACPI / battery: A... |
1030 1031 1032 |
acpi_battery_init_alarm(battery); acpi_battery_get_state(battery); |
25be58215 ACPI battery: fri... |
1033 1034 1035 1036 1037 |
break; } return 0; } |
048d16da7 ACPI / battery: m... |
1038 1039 |
static int __init battery_bix_broken_package_quirk(const struct dmi_system_id *d) |
3f5dc08f5 ACPI / battery: u... |
1040 1041 1042 1043 |
{ battery_bix_broken_package = 1; return 0; } |
048d16da7 ACPI / battery: m... |
1044 1045 |
static int __init battery_notification_delay_quirk(const struct dmi_system_id *d) |
f43691c61 ACPI / battery: a... |
1046 1047 1048 1049 |
{ battery_notification_delay_ms = 1000; return 0; } |
1b799c5cf ACPI / battery: I... |
1050 1051 1052 1053 1054 1055 |
static int __init battery_ac_is_broken_quirk(const struct dmi_system_id *d) { battery_ac_is_broken = 1; return 0; } |
ec625a37c ACPI / battery: A... |
1056 1057 1058 1059 1060 1061 |
static int __init battery_do_not_check_pmic_quirk(const struct dmi_system_id *d) { battery_check_pmic = 0; return 0; } |
048d16da7 ACPI / battery: m... |
1062 |
static const struct dmi_system_id bat_dmi_table[] __initconst = { |
a90b40385 ACPI / Battery: A... |
1063 |
{ |
91afa0766 ACPI / battery: R... |
1064 |
/* NEC LZ750/LS */ |
3f5dc08f5 ACPI / battery: u... |
1065 |
.callback = battery_bix_broken_package_quirk, |
a90b40385 ACPI / Battery: A... |
1066 1067 1068 1069 1070 |
.matches = { DMI_MATCH(DMI_SYS_VENDOR, "NEC"), DMI_MATCH(DMI_PRODUCT_NAME, "PC-LZ750LS"), }, }, |
f43691c61 ACPI / battery: a... |
1071 |
{ |
91afa0766 ACPI / battery: R... |
1072 |
/* Acer Aspire V5-573G */ |
f43691c61 ACPI / battery: a... |
1073 |
.callback = battery_notification_delay_quirk, |
f43691c61 ACPI / battery: a... |
1074 1075 1076 1077 1078 |
.matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-573G"), }, }, |
1b799c5cf ACPI / battery: I... |
1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 |
{ /* Point of View mobii wintab p800w */ .callback = battery_ac_is_broken_quirk, .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), DMI_MATCH(DMI_BIOS_VERSION, "3BAIR1013"), /* Above matches are too generic, add bios-date match */ DMI_MATCH(DMI_BIOS_DATE, "08/22/2014"), }, }, |
ec625a37c ACPI / battery: A... |
1090 |
{ |
8c3f6993c ACPI / battery: C... |
1091 |
/* ECS EF20EA, AXP288 PMIC but uses separate fuel-gauge */ |
ec625a37c ACPI / battery: A... |
1092 1093 1094 1095 1096 1097 |
.callback = battery_do_not_check_pmic_quirk, .matches = { DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"), }, }, { |
8c3f6993c ACPI / battery: C... |
1098 |
/* Lenovo Ideapad Miix 320, AXP288 PMIC, separate fuel-gauge */ |
ec625a37c ACPI / battery: A... |
1099 1100 |
.callback = battery_do_not_check_pmic_quirk, .matches = { |
8c3f6993c ACPI / battery: C... |
1101 1102 1103 |
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "80XF"), DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"), |
ec625a37c ACPI / battery: A... |
1104 1105 |
}, }, |
a90b40385 ACPI / Battery: A... |
1106 1107 |
{}, }; |
75646e758 ACPI / battery: R... |
1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 |
/* * Some machines'(E,G Lenovo Z480) ECs are not stable * during boot up and this causes battery driver fails to be * probed due to failure of getting battery information * from EC sometimes. After several retries, the operation * may work. So add retry code here and 20ms sleep between * every retries. */ static int acpi_battery_update_retry(struct acpi_battery *battery) { int retry, ret; for (retry = 5; retry; retry--) { ret = acpi_battery_update(battery, false); if (!ret) break; msleep(20); } return ret; } |
4be44fcd3 [ACPI] Lindent al... |
1129 |
static int acpi_battery_add(struct acpi_device *device) |
1da177e4c Linux-2.6.12-rc2 |
1130 |
{ |
4be44fcd3 [ACPI] Lindent al... |
1131 |
int result = 0; |
4be44fcd3 [ACPI] Lindent al... |
1132 |
struct acpi_battery *battery = NULL; |
952c63e95 ACPI: introduce h... |
1133 |
|
1da177e4c Linux-2.6.12-rc2 |
1134 |
if (!device) |
d550d98d3 ACPI: delete trac... |
1135 |
return -EINVAL; |
40e7fcb19 ACPI: Add _DEP su... |
1136 1137 1138 |
if (device->dep_unmet) return -EPROBE_DEFER; |
36bcbec7c ACPI: replace kma... |
1139 |
battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
1140 |
if (!battery) |
d550d98d3 ACPI: delete trac... |
1141 |
return -ENOMEM; |
145def84a ACPI: battery: ad... |
1142 |
battery->device = device; |
1da177e4c Linux-2.6.12-rc2 |
1143 1144 |
strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); |
db89b4f0d ACPI: catch calls... |
1145 |
device->driver_data = battery; |
038fdea29 ACPI: Battery: do... |
1146 |
mutex_init(&battery->lock); |
69d94ec6d Battery: sysfs_re... |
1147 |
mutex_init(&battery->sysfs_lock); |
952c63e95 ACPI: introduce h... |
1148 |
if (acpi_has_method(battery->device->handle, "_BIX")) |
c67fcd670 ACPI: Battery: Ad... |
1149 |
set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); |
75646e758 ACPI / battery: R... |
1150 1151 |
result = acpi_battery_update_retry(battery); |
eb03cb02b ACPI / Battery: p... |
1152 1153 |
if (result) goto fail; |
75646e758 ACPI / battery: R... |
1154 |
|
dd1fca9e6 ACPI / battery: u... |
1155 1156 |
pr_info(PREFIX "%s Slot [%s] (battery %s) ", |
e80bba4b5 ACPI / Battery: a... |
1157 1158 |
ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), device->status.battery_present ? "present" : "absent"); |
25be58215 ACPI battery: fri... |
1159 1160 |
battery->pm_nb.notifier_call = battery_notify; register_pm_notifier(&battery->pm_nb); |
e0d1f09e3 ACPI / battery: w... |
1161 |
device_init_wakeup(&device->dev, 1); |
d550d98d3 ACPI: delete trac... |
1162 |
return result; |
e80bba4b5 ACPI / Battery: a... |
1163 1164 1165 1166 |
fail: sysfs_remove_battery(battery); mutex_destroy(&battery->lock); |
69d94ec6d Battery: sysfs_re... |
1167 |
mutex_destroy(&battery->sysfs_lock); |
e80bba4b5 ACPI / Battery: a... |
1168 1169 |
kfree(battery); return result; |
1da177e4c Linux-2.6.12-rc2 |
1170 |
} |
51fac8388 ACPI: Remove usel... |
1171 |
static int acpi_battery_remove(struct acpi_device *device) |
1da177e4c Linux-2.6.12-rc2 |
1172 |
{ |
4be44fcd3 [ACPI] Lindent al... |
1173 |
struct acpi_battery *battery = NULL; |
1da177e4c Linux-2.6.12-rc2 |
1174 |
|
1da177e4c Linux-2.6.12-rc2 |
1175 |
if (!device || !acpi_driver_data(device)) |
d550d98d3 ACPI: delete trac... |
1176 |
return -EINVAL; |
e0d1f09e3 ACPI / battery: w... |
1177 |
device_init_wakeup(&device->dev, 0); |
50dd09697 ACPI: Remove unne... |
1178 |
battery = acpi_driver_data(device); |
25be58215 ACPI battery: fri... |
1179 |
unregister_pm_notifier(&battery->pm_nb); |
508df92d1 ACPI: battery: re... |
1180 |
sysfs_remove_battery(battery); |
038fdea29 ACPI: Battery: do... |
1181 |
mutex_destroy(&battery->lock); |
69d94ec6d Battery: sysfs_re... |
1182 |
mutex_destroy(&battery->sysfs_lock); |
1da177e4c Linux-2.6.12-rc2 |
1183 |
kfree(battery); |
d550d98d3 ACPI: delete trac... |
1184 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
1185 |
} |
906924048 ACPI / PM: Fix un... |
1186 |
#ifdef CONFIG_PM_SLEEP |
34c4415ab ACPI: check batte... |
1187 |
/* this is needed to learn about changes made in suspended state */ |
a6f50dc8e ACPI: Use struct ... |
1188 |
static int acpi_battery_resume(struct device *dev) |
34c4415ab ACPI: check batte... |
1189 1190 |
{ struct acpi_battery *battery; |
a6f50dc8e ACPI: Use struct ... |
1191 1192 |
if (!dev) |
34c4415ab ACPI: check batte... |
1193 |
return -EINVAL; |
a6f50dc8e ACPI: Use struct ... |
1194 1195 1196 1197 |
battery = acpi_driver_data(to_acpi_device(dev)); if (!battery) return -EINVAL; |
f1d4661ab ACPI: Battery: si... |
1198 |
battery->update_time = 0; |
9e50bc14a ACPI / battery: A... |
1199 |
acpi_battery_update(battery, true); |
b6ce4083e ACPI: Cache batte... |
1200 |
return 0; |
34c4415ab ACPI: check batte... |
1201 |
} |
7f6895c60 ACPI / battery: f... |
1202 1203 |
#else #define acpi_battery_resume NULL |
906924048 ACPI / PM: Fix un... |
1204 |
#endif |
34c4415ab ACPI: check batte... |
1205 |
|
a6f50dc8e ACPI: Use struct ... |
1206 |
static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume); |
aa650bbdc ACPI: Battery: Mi... |
1207 1208 1209 1210 |
static struct acpi_driver acpi_battery_driver = { .name = "battery", .class = ACPI_BATTERY_CLASS, .ids = battery_device_ids, |
d94066910 ACPI: battery: us... |
1211 |
.flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, |
aa650bbdc ACPI: Battery: Mi... |
1212 1213 |
.ops = { .add = acpi_battery_add, |
aa650bbdc ACPI: Battery: Mi... |
1214 |
.remove = acpi_battery_remove, |
d94066910 ACPI: battery: us... |
1215 |
.notify = acpi_battery_notify, |
aa650bbdc ACPI: Battery: Mi... |
1216 |
}, |
a6f50dc8e ACPI: Use struct ... |
1217 |
.drv.pm = &acpi_battery_pm, |
aa650bbdc ACPI: Battery: Mi... |
1218 |
}; |
b0cbc861a Revert "ACPI batt... |
1219 |
static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie) |
1da177e4c Linux-2.6.12-rc2 |
1220 |
{ |
dccfae6d4 ACPI / battery: A... |
1221 |
unsigned int i; |
479faaf00 ACPI / battery: d... |
1222 |
int result; |
3f5dc08f5 ACPI / battery: u... |
1223 |
dmi_check_system(bat_dmi_table); |
479faaf00 ACPI / battery: d... |
1224 |
|
ec625a37c ACPI / battery: A... |
1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 |
if (battery_check_pmic) { for (i = 0; i < ARRAY_SIZE(acpi_battery_blacklist); i++) if (acpi_dev_present(acpi_battery_blacklist[i], "1", -1)) { pr_info(PREFIX ACPI_BATTERY_DEVICE_NAME ": found native %s PMIC, not loading ", acpi_battery_blacklist[i]); return; } } |
479faaf00 ACPI / battery: d... |
1235 |
result = acpi_bus_register_driver(&acpi_battery_driver); |
bc39fbcf9 ACPI / battery: F... |
1236 |
battery_driver_registered = (result == 0); |
0f66af530 ACPI: battery: as... |
1237 1238 1239 1240 |
} static int __init acpi_battery_init(void) { |
e234b074c ACPI / battery: a... |
1241 1242 |
if (acpi_disabled) return -ENODEV; |
eca21d916 ACPI / battery: e... |
1243 |
async_cookie = async_schedule(acpi_battery_init_async, NULL); |
d550d98d3 ACPI: delete trac... |
1244 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
1245 |
} |
4be44fcd3 [ACPI] Lindent al... |
1246 |
static void __exit acpi_battery_exit(void) |
1da177e4c Linux-2.6.12-rc2 |
1247 |
{ |
5dfa0c739 ACPI / battery: C... |
1248 |
async_synchronize_cookie(async_cookie + 1); |
fa93854f7 battery: Add the ... |
1249 |
if (battery_driver_registered) { |
bc39fbcf9 ACPI / battery: F... |
1250 |
acpi_bus_unregister_driver(&acpi_battery_driver); |
fa93854f7 battery: Add the ... |
1251 1252 |
battery_hook_exit(); } |
1da177e4c Linux-2.6.12-rc2 |
1253 |
} |
1da177e4c Linux-2.6.12-rc2 |
1254 1255 |
module_init(acpi_battery_init); module_exit(acpi_battery_exit); |