Blame view
drivers/acpi/battery.c
31.3 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
aa650bbdc ACPI: Battery: Mi... |
2 |
* battery.c - ACPI Battery Driver (Revision: 2.0) |
1da177e4c Linux-2.6.12-rc2 |
3 |
* |
aa650bbdc ACPI: Battery: Mi... |
4 5 |
* 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 |
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/types.h> |
f1d4661ab ACPI: Battery: si... |
32 |
#include <linux/jiffies.h> |
0f66af530 ACPI: battery: as... |
33 |
#include <linux/async.h> |
bc76f90b8 ACPI battery: wor... |
34 |
#include <linux/dmi.h> |
5a0e3ad6a include cleanup: ... |
35 |
#include <linux/slab.h> |
25be58215 ACPI battery: fri... |
36 |
#include <linux/suspend.h> |
d73809657 ACPI: Battery: Ad... |
37 |
|
fdcedbba2 ACPI: Split out c... |
38 |
#ifdef CONFIG_ACPI_PROCFS_POWER |
1da177e4c Linux-2.6.12-rc2 |
39 40 41 |
#include <linux/proc_fs.h> #include <linux/seq_file.h> #include <asm/uaccess.h> |
d73809657 ACPI: Battery: Ad... |
42 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
43 44 45 |
#include <acpi/acpi_bus.h> #include <acpi/acpi_drivers.h> |
d73809657 ACPI: Battery: Ad... |
46 |
#include <linux/power_supply.h> |
a192a9580 ACPI: Move defini... |
47 |
#define PREFIX "ACPI: " |
1da177e4c Linux-2.6.12-rc2 |
48 |
#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF |
1da177e4c Linux-2.6.12-rc2 |
49 |
#define ACPI_BATTERY_CLASS "battery" |
1da177e4c Linux-2.6.12-rc2 |
50 |
#define ACPI_BATTERY_DEVICE_NAME "Battery" |
1da177e4c Linux-2.6.12-rc2 |
51 52 |
#define ACPI_BATTERY_NOTIFY_STATUS 0x80 #define ACPI_BATTERY_NOTIFY_INFO 0x81 |
c67fcd670 ACPI: Battery: Ad... |
53 |
#define ACPI_BATTERY_NOTIFY_THRESHOLD 0x82 |
1da177e4c Linux-2.6.12-rc2 |
54 |
|
ae6f61870 ACPI / Battery: A... |
55 56 |
/* Battery power unit: 0 means mW, 1 means mA */ #define ACPI_BATTERY_POWER_UNIT_MA 1 |
1da177e4c Linux-2.6.12-rc2 |
57 |
#define _COMPONENT ACPI_BATTERY_COMPONENT |
b6ce4083e ACPI: Cache batte... |
58 |
|
f52fd66d2 ACPI: clean up AC... |
59 |
ACPI_MODULE_NAME("battery"); |
1da177e4c Linux-2.6.12-rc2 |
60 |
|
f52fd66d2 ACPI: clean up AC... |
61 |
MODULE_AUTHOR("Paul Diefenbaugh"); |
aa650bbdc ACPI: Battery: Mi... |
62 |
MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>"); |
7cda93e00 ACPI: delete extr... |
63 |
MODULE_DESCRIPTION("ACPI Battery Driver"); |
1da177e4c Linux-2.6.12-rc2 |
64 |
MODULE_LICENSE("GPL"); |
f1d4661ab ACPI: Battery: si... |
65 66 67 |
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... |
68 |
|
fdcedbba2 ACPI: Split out c... |
69 |
#ifdef CONFIG_ACPI_PROCFS_POWER |
3f86b8324 ACPI: add support... |
70 71 |
extern struct proc_dir_entry *acpi_lock_battery_dir(void); extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); |
d73809657 ACPI: Battery: Ad... |
72 73 74 75 76 77 78 79 |
enum acpi_battery_files { info_tag = 0, state_tag, alarm_tag, ACPI_BATTERY_NUMFILES, }; #endif |
1ba90e3a8 ACPI: autoload mo... |
80 81 82 83 |
static const struct acpi_device_id battery_device_ids[] = { {"PNP0C0A", 0}, {"", 0}, }; |
1ba90e3a8 ACPI: autoload mo... |
84 |
|
aa650bbdc ACPI: Battery: Mi... |
85 |
MODULE_DEVICE_TABLE(acpi, battery_device_ids); |
1da177e4c Linux-2.6.12-rc2 |
86 |
|
7b3bcc4a1 ACPI: Battery: Ad... |
87 88 |
enum { ACPI_BATTERY_ALARM_PRESENT, |
c67fcd670 ACPI: Battery: Ad... |
89 |
ACPI_BATTERY_XINFO_PRESENT, |
557d58687 ACPI battery: sup... |
90 |
ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, |
7b3bcc4a1 ACPI: Battery: Ad... |
91 |
}; |
78490d821 ACPI: battery: sy... |
92 |
|
1da177e4c Linux-2.6.12-rc2 |
93 |
struct acpi_battery { |
038fdea29 ACPI: Battery: do... |
94 |
struct mutex lock; |
69d94ec6d Battery: sysfs_re... |
95 |
struct mutex sysfs_lock; |
d73809657 ACPI: Battery: Ad... |
96 |
struct power_supply bat; |
f1d4661ab ACPI: Battery: si... |
97 |
struct acpi_device *device; |
25be58215 ACPI battery: fri... |
98 |
struct notifier_block pm_nb; |
f1d4661ab ACPI: Battery: si... |
99 |
unsigned long update_time; |
7faa144a5 ACPI: battery: ad... |
100 |
int rate_now; |
d73809657 ACPI: Battery: Ad... |
101 102 |
int capacity_now; int voltage_now; |
038fdea29 ACPI: Battery: do... |
103 |
int design_capacity; |
d73809657 ACPI: Battery: Ad... |
104 |
int full_charge_capacity; |
038fdea29 ACPI: Battery: do... |
105 106 107 108 |
int technology; int design_voltage; int design_capacity_warning; int design_capacity_low; |
c67fcd670 ACPI: Battery: Ad... |
109 110 111 112 113 114 |
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... |
115 116 |
int capacity_granularity_1; int capacity_granularity_2; |
f1d4661ab ACPI: Battery: si... |
117 |
int alarm; |
038fdea29 ACPI: Battery: do... |
118 119 120 121 |
char model_number[32]; char serial_number[32]; char type[32]; char oem_info[32]; |
f1d4661ab ACPI: Battery: si... |
122 123 |
int state; int power_unit; |
7b3bcc4a1 ACPI: Battery: Ad... |
124 |
unsigned long flags; |
1da177e4c Linux-2.6.12-rc2 |
125 |
}; |
497888cf6 treewide: fix pot... |
126 |
#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat) |
d73809657 ACPI: Battery: Ad... |
127 |
|
78490d821 ACPI: battery: sy... |
128 |
inline int acpi_battery_present(struct acpi_battery *battery) |
b6ce4083e ACPI: Cache batte... |
129 |
{ |
78490d821 ACPI: battery: sy... |
130 131 |
return battery->device->status.battery_present; } |
038fdea29 ACPI: Battery: do... |
132 |
|
d73809657 ACPI: Battery: Ad... |
133 134 135 136 137 138 139 140 |
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... |
141 |
if (!strncasecmp("LI-ION", battery->type, 6)) |
0bde7eee9 ACPI: battery: Su... |
142 |
return POWER_SUPPLY_TECHNOLOGY_LION; |
d73809657 ACPI: Battery: Ad... |
143 144 145 146 |
if (!strcasecmp("LiP", battery->type)) return POWER_SUPPLY_TECHNOLOGY_LIPO; return POWER_SUPPLY_TECHNOLOGY_UNKNOWN; } |
9104476e4 ACPI: Battery: re... |
147 |
static int acpi_battery_get_state(struct acpi_battery *battery); |
b19073a0b ACPI: battery: Up... |
148 |
|
56f382a08 battery: don't as... |
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
static int acpi_battery_is_charged(struct acpi_battery *battery) { /* either charging or discharging */ 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; } |
d73809657 ACPI: Battery: Ad... |
171 172 173 174 |
static int acpi_battery_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) { |
a1b4bd694 ACPI / Battery: R... |
175 |
int ret = 0; |
d73809657 ACPI: Battery: Ad... |
176 |
struct acpi_battery *battery = to_acpi_battery(psy); |
9104476e4 ACPI: Battery: re... |
177 178 179 180 |
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... |
181 182 183 184 185 186 187 |
return -ENODEV; switch (psp) { case POWER_SUPPLY_PROP_STATUS: if (battery->state & 0x01) val->intval = POWER_SUPPLY_STATUS_DISCHARGING; else if (battery->state & 0x02) val->intval = POWER_SUPPLY_STATUS_CHARGING; |
56f382a08 battery: don't as... |
188 |
else if (acpi_battery_is_charged(battery)) |
d73809657 ACPI: Battery: Ad... |
189 |
val->intval = POWER_SUPPLY_STATUS_FULL; |
4c41d3ad6 ACPI: Always retu... |
190 191 |
else val->intval = POWER_SUPPLY_STATUS_UNKNOWN; |
d73809657 ACPI: Battery: Ad... |
192 193 194 195 196 197 198 |
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... |
199 200 201 |
case POWER_SUPPLY_PROP_CYCLE_COUNT: val->intval = battery->cycle_count; break; |
d73809657 ACPI: Battery: Ad... |
202 |
case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: |
a1b4bd694 ACPI / Battery: R... |
203 204 205 206 |
if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) ret = -ENODEV; else val->intval = battery->design_voltage * 1000; |
d73809657 ACPI: Battery: Ad... |
207 208 |
break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: |
a1b4bd694 ACPI / Battery: R... |
209 210 211 212 |
if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN) ret = -ENODEV; else val->intval = battery->voltage_now * 1000; |
d73809657 ACPI: Battery: Ad... |
213 214 |
break; case POWER_SUPPLY_PROP_CURRENT_NOW: |
7faa144a5 ACPI: battery: ad... |
215 |
case POWER_SUPPLY_PROP_POWER_NOW: |
a1b4bd694 ACPI / Battery: R... |
216 217 218 219 |
if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN) ret = -ENODEV; else val->intval = battery->rate_now * 1000; |
d73809657 ACPI: Battery: Ad... |
220 221 222 |
break; case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: |
a1b4bd694 ACPI / Battery: R... |
223 224 225 226 |
if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) ret = -ENODEV; else val->intval = battery->design_capacity * 1000; |
d73809657 ACPI: Battery: Ad... |
227 228 229 |
break; case POWER_SUPPLY_PROP_CHARGE_FULL: case POWER_SUPPLY_PROP_ENERGY_FULL: |
a1b4bd694 ACPI / Battery: R... |
230 231 232 233 |
if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN) ret = -ENODEV; else val->intval = battery->full_charge_capacity * 1000; |
d73809657 ACPI: Battery: Ad... |
234 235 236 |
break; case POWER_SUPPLY_PROP_CHARGE_NOW: case POWER_SUPPLY_PROP_ENERGY_NOW: |
a1b4bd694 ACPI / Battery: R... |
237 238 239 240 |
if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN) ret = -ENODEV; else val->intval = battery->capacity_now * 1000; |
d73809657 ACPI: Battery: Ad... |
241 242 243 244 245 246 247 |
break; 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... |
248 249 250 |
case POWER_SUPPLY_PROP_SERIAL_NUMBER: val->strval = battery->serial_number; break; |
d73809657 ACPI: Battery: Ad... |
251 |
default: |
a1b4bd694 ACPI / Battery: R... |
252 |
ret = -EINVAL; |
d73809657 ACPI: Battery: Ad... |
253 |
} |
a1b4bd694 ACPI / Battery: R... |
254 |
return ret; |
d73809657 ACPI: Battery: Ad... |
255 256 257 258 259 260 |
} static enum power_supply_property charge_battery_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_TECHNOLOGY, |
c67fcd670 ACPI: Battery: Ad... |
261 |
POWER_SUPPLY_PROP_CYCLE_COUNT, |
d73809657 ACPI: Battery: Ad... |
262 263 264 265 266 267 268 269 |
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, POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_MANUFACTURER, |
7c2670bbb ACPI: battery: ad... |
270 |
POWER_SUPPLY_PROP_SERIAL_NUMBER, |
d73809657 ACPI: Battery: Ad... |
271 272 273 274 275 276 |
}; static enum power_supply_property energy_battery_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_TECHNOLOGY, |
c67fcd670 ACPI: Battery: Ad... |
277 |
POWER_SUPPLY_PROP_CYCLE_COUNT, |
d73809657 ACPI: Battery: Ad... |
278 279 |
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, POWER_SUPPLY_PROP_VOLTAGE_NOW, |
7faa144a5 ACPI: battery: ad... |
280 |
POWER_SUPPLY_PROP_POWER_NOW, |
d73809657 ACPI: Battery: Ad... |
281 282 283 284 285 |
POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, POWER_SUPPLY_PROP_ENERGY_FULL, POWER_SUPPLY_PROP_ENERGY_NOW, POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_MANUFACTURER, |
7c2670bbb ACPI: battery: ad... |
286 |
POWER_SUPPLY_PROP_SERIAL_NUMBER, |
d73809657 ACPI: Battery: Ad... |
287 |
}; |
fdcedbba2 ACPI: Split out c... |
288 |
#ifdef CONFIG_ACPI_PROCFS_POWER |
f1d4661ab ACPI: Battery: si... |
289 |
inline char *acpi_battery_units(struct acpi_battery *battery) |
78490d821 ACPI: battery: sy... |
290 |
{ |
ae6f61870 ACPI / Battery: A... |
291 292 |
return (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) ? "mA" : "mW"; |
b6ce4083e ACPI: Cache batte... |
293 |
} |
d73809657 ACPI: Battery: Ad... |
294 |
#endif |
b6ce4083e ACPI: Cache batte... |
295 |
|
78490d821 ACPI: battery: sy... |
296 297 298 |
/* -------------------------------------------------------------------------- Battery Management -------------------------------------------------------------------------- */ |
038fdea29 ACPI: Battery: do... |
299 300 301 302 |
struct acpi_offsets { size_t offset; /* offset inside struct acpi_sbs_battery */ u8 mode; /* int or string? */ }; |
b6ce4083e ACPI: Cache batte... |
303 |
|
038fdea29 ACPI: Battery: do... |
304 305 |
static struct acpi_offsets state_offsets[] = { {offsetof(struct acpi_battery, state), 0}, |
7faa144a5 ACPI: battery: ad... |
306 |
{offsetof(struct acpi_battery, rate_now), 0}, |
d73809657 ACPI: Battery: Ad... |
307 308 |
{offsetof(struct acpi_battery, capacity_now), 0}, {offsetof(struct acpi_battery, voltage_now), 0}, |
038fdea29 ACPI: Battery: do... |
309 |
}; |
b6ce4083e ACPI: Cache batte... |
310 |
|
038fdea29 ACPI: Battery: do... |
311 312 313 |
static struct acpi_offsets info_offsets[] = { {offsetof(struct acpi_battery, power_unit), 0}, {offsetof(struct acpi_battery, design_capacity), 0}, |
d73809657 ACPI: Battery: Ad... |
314 |
{offsetof(struct acpi_battery, full_charge_capacity), 0}, |
038fdea29 ACPI: Battery: do... |
315 316 317 318 319 320 321 322 323 324 325 |
{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... |
326 |
|
c67fcd670 ACPI: Battery: Ad... |
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 |
static struct acpi_offsets extended_info_offsets[] = { {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... |
348 349 350 351 |
static int extract_package(struct acpi_battery *battery, union acpi_object *package, struct acpi_offsets *offsets, int num) { |
106449e87 ACPI: Battery: Al... |
352 |
int i; |
038fdea29 ACPI: Battery: do... |
353 354 355 356 357 358 359 360 |
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... |
361 362 363 364 365 366 |
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... |
367 368 |
sizeof(u64)); ptr[sizeof(u64)] = 0; |
b8a1bdb14 ACPI: battery: Do... |
369 370 |
} else *ptr = 0; /* don't have value */ |
038fdea29 ACPI: Battery: do... |
371 |
} else { |
b8a1bdb14 ACPI: battery: Do... |
372 373 374 |
int *x = (int *)((u8 *)battery + offsets[i].offset); *x = (element->type == ACPI_TYPE_INTEGER) ? element->integer.value : -1; |
038fdea29 ACPI: Battery: do... |
375 |
} |
b6ce4083e ACPI: Cache batte... |
376 |
} |
b6ce4083e ACPI: Cache batte... |
377 378 379 380 381 |
return 0; } static int acpi_battery_get_status(struct acpi_battery *battery) { |
aa650bbdc ACPI: Battery: Mi... |
382 |
if (acpi_bus_get_status(battery->device)) { |
b6ce4083e ACPI: Cache batte... |
383 384 385 |
ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA")); return -ENODEV; } |
aa650bbdc ACPI: Battery: Mi... |
386 |
return 0; |
b6ce4083e ACPI: Cache batte... |
387 388 389 |
} static int acpi_battery_get_info(struct acpi_battery *battery) |
1da177e4c Linux-2.6.12-rc2 |
390 |
{ |
aa650bbdc ACPI: Battery: Mi... |
391 |
int result = -EFAULT; |
4be44fcd3 [ACPI] Lindent al... |
392 |
acpi_status status = 0; |
c67fcd670 ACPI: Battery: Ad... |
393 394 |
char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags)? "_BIX" : "_BIF"; |
4be44fcd3 [ACPI] Lindent al... |
395 |
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
1da177e4c Linux-2.6.12-rc2 |
396 |
|
b6ce4083e ACPI: Cache batte... |
397 398 |
if (!acpi_battery_present(battery)) return 0; |
038fdea29 ACPI: Battery: do... |
399 |
mutex_lock(&battery->lock); |
c67fcd670 ACPI: Battery: Ad... |
400 401 |
status = acpi_evaluate_object(battery->device->handle, name, NULL, &buffer); |
038fdea29 ACPI: Battery: do... |
402 |
mutex_unlock(&battery->lock); |
aa650bbdc ACPI: Battery: Mi... |
403 |
|
1da177e4c Linux-2.6.12-rc2 |
404 |
if (ACPI_FAILURE(status)) { |
c67fcd670 ACPI: Battery: Ad... |
405 |
ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s", name)); |
d550d98d3 ACPI: delete trac... |
406 |
return -ENODEV; |
1da177e4c Linux-2.6.12-rc2 |
407 |
} |
c67fcd670 ACPI: Battery: Ad... |
408 409 410 411 412 413 414 |
if (test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags)) result = extract_package(battery, buffer.pointer, extended_info_offsets, ARRAY_SIZE(extended_info_offsets)); else result = extract_package(battery, buffer.pointer, info_offsets, ARRAY_SIZE(info_offsets)); |
78490d821 ACPI: battery: sy... |
415 |
kfree(buffer.pointer); |
557d58687 ACPI battery: sup... |
416 417 |
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)) battery->full_charge_capacity = battery->design_capacity; |
d550d98d3 ACPI: delete trac... |
418 |
return result; |
1da177e4c Linux-2.6.12-rc2 |
419 |
} |
b6ce4083e ACPI: Cache batte... |
420 |
static int acpi_battery_get_state(struct acpi_battery *battery) |
1da177e4c Linux-2.6.12-rc2 |
421 |
{ |
4be44fcd3 [ACPI] Lindent al... |
422 423 424 |
int result = 0; acpi_status status = 0; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
1da177e4c Linux-2.6.12-rc2 |
425 |
|
b6ce4083e ACPI: Cache batte... |
426 427 |
if (!acpi_battery_present(battery)) return 0; |
1da177e4c Linux-2.6.12-rc2 |
428 |
|
f1d4661ab ACPI: Battery: si... |
429 430 431 432 |
if (battery->update_time && time_before(jiffies, battery->update_time + msecs_to_jiffies(cache_time))) return 0; |
038fdea29 ACPI: Battery: do... |
433 |
mutex_lock(&battery->lock); |
f1d4661ab ACPI: Battery: si... |
434 |
status = acpi_evaluate_object(battery->device->handle, "_BST", |
038fdea29 ACPI: Battery: do... |
435 436 |
NULL, &buffer); mutex_unlock(&battery->lock); |
5b31d8958 Revert "ACPI: Bat... |
437 |
|
1da177e4c Linux-2.6.12-rc2 |
438 |
if (ACPI_FAILURE(status)) { |
a6fc67202 ACPI: Enable ACPI... |
439 |
ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); |
d550d98d3 ACPI: delete trac... |
440 |
return -ENODEV; |
1da177e4c Linux-2.6.12-rc2 |
441 |
} |
aa650bbdc ACPI: Battery: Mi... |
442 |
|
038fdea29 ACPI: Battery: do... |
443 444 |
result = extract_package(battery, buffer.pointer, state_offsets, ARRAY_SIZE(state_offsets)); |
f1d4661ab ACPI: Battery: si... |
445 |
battery->update_time = jiffies; |
78490d821 ACPI: battery: sy... |
446 |
kfree(buffer.pointer); |
bc76f90b8 ACPI battery: wor... |
447 |
|
55003b210 ACPI / Battery: C... |
448 449 450 451 452 453 454 |
/* 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... |
455 |
battery->rate_now = abs((s16)battery->rate_now); |
55003b210 ACPI / Battery: C... |
456 457 458 459 |
printk_once(KERN_WARNING FW_BUG "battery: (dis)charge rate" " invalid. "); } |
bc76f90b8 ACPI battery: wor... |
460 |
|
557d58687 ACPI battery: sup... |
461 462 463 464 |
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; |
b6ce4083e ACPI: Cache batte... |
465 466 |
return result; } |
1da177e4c Linux-2.6.12-rc2 |
467 |
|
aa650bbdc ACPI: Battery: Mi... |
468 |
static int acpi_battery_set_alarm(struct acpi_battery *battery) |
1da177e4c Linux-2.6.12-rc2 |
469 |
{ |
4be44fcd3 [ACPI] Lindent al... |
470 |
acpi_status status = 0; |
aa650bbdc ACPI: Battery: Mi... |
471 |
union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER }; |
4be44fcd3 [ACPI] Lindent al... |
472 |
struct acpi_object_list arg_list = { 1, &arg0 }; |
1da177e4c Linux-2.6.12-rc2 |
473 |
|
c67fcd670 ACPI: Battery: Ad... |
474 |
if (!acpi_battery_present(battery) || |
7b3bcc4a1 ACPI: Battery: Ad... |
475 |
!test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags)) |
d550d98d3 ACPI: delete trac... |
476 |
return -ENODEV; |
1da177e4c Linux-2.6.12-rc2 |
477 |
|
aa650bbdc ACPI: Battery: Mi... |
478 |
arg0.integer.value = battery->alarm; |
1da177e4c Linux-2.6.12-rc2 |
479 |
|
038fdea29 ACPI: Battery: do... |
480 |
mutex_lock(&battery->lock); |
f1d4661ab ACPI: Battery: si... |
481 482 |
status = acpi_evaluate_object(battery->device->handle, "_BTP", &arg_list, NULL); |
038fdea29 ACPI: Battery: do... |
483 |
mutex_unlock(&battery->lock); |
aa650bbdc ACPI: Battery: Mi... |
484 |
|
1da177e4c Linux-2.6.12-rc2 |
485 |
if (ACPI_FAILURE(status)) |
d550d98d3 ACPI: delete trac... |
486 |
return -ENODEV; |
1da177e4c Linux-2.6.12-rc2 |
487 |
|
aa650bbdc ACPI: Battery: Mi... |
488 489 |
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d ", battery->alarm)); |
d550d98d3 ACPI: delete trac... |
490 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
491 |
} |
b6ce4083e ACPI: Cache batte... |
492 |
static int acpi_battery_init_alarm(struct acpi_battery *battery) |
1da177e4c Linux-2.6.12-rc2 |
493 |
{ |
4be44fcd3 [ACPI] Lindent al... |
494 495 |
acpi_status status = AE_OK; acpi_handle handle = NULL; |
4be44fcd3 [ACPI] Lindent al... |
496 |
|
b6ce4083e ACPI: Cache batte... |
497 |
/* See if alarms are supported, and if so, set default */ |
f1d4661ab ACPI: Battery: si... |
498 499 |
status = acpi_get_handle(battery->device->handle, "_BTP", &handle); if (ACPI_FAILURE(status)) { |
7b3bcc4a1 ACPI: Battery: Ad... |
500 |
clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags); |
f1d4661ab ACPI: Battery: si... |
501 |
return 0; |
b6ce4083e ACPI: Cache batte... |
502 |
} |
7b3bcc4a1 ACPI: Battery: Ad... |
503 |
set_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags); |
f1d4661ab ACPI: Battery: si... |
504 505 |
if (!battery->alarm) battery->alarm = battery->design_capacity_warning; |
aa650bbdc ACPI: Battery: Mi... |
506 |
return acpi_battery_set_alarm(battery); |
b6ce4083e ACPI: Cache batte... |
507 |
} |
1da177e4c Linux-2.6.12-rc2 |
508 |
|
508df92d1 ACPI: battery: re... |
509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 |
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)); if (sscanf(buf, "%ld ", &x) == 1) battery->alarm = x/1000; if (acpi_battery_present(battery)) acpi_battery_set_alarm(battery); return count; } static struct device_attribute alarm_attr = { |
01e8ef11b x86: sysfs: kill ... |
533 |
.attr = {.name = "alarm", .mode = 0644}, |
508df92d1 ACPI: battery: re... |
534 535 536 537 538 539 540 |
.show = acpi_battery_alarm_show, .store = acpi_battery_alarm_store, }; static int sysfs_add_battery(struct acpi_battery *battery) { int result; |
ae6f61870 ACPI / Battery: A... |
541 |
if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) { |
508df92d1 ACPI: battery: re... |
542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 |
battery->bat.properties = charge_battery_props; battery->bat.num_properties = ARRAY_SIZE(charge_battery_props); } else { battery->bat.properties = energy_battery_props; battery->bat.num_properties = ARRAY_SIZE(energy_battery_props); } battery->bat.name = acpi_device_bid(battery->device); battery->bat.type = POWER_SUPPLY_TYPE_BATTERY; battery->bat.get_property = acpi_battery_get_property; result = power_supply_register(&battery->device->dev, &battery->bat); if (result) return result; return device_create_file(battery->bat.dev, &alarm_attr); } static void sysfs_remove_battery(struct acpi_battery *battery) { |
69d94ec6d Battery: sysfs_re... |
563 |
mutex_lock(&battery->sysfs_lock); |
9c921c22a ACPI / Battery: R... |
564 |
if (!battery->bat.dev) { |
69d94ec6d Battery: sysfs_re... |
565 |
mutex_unlock(&battery->sysfs_lock); |
508df92d1 ACPI: battery: re... |
566 |
return; |
9c921c22a ACPI / Battery: R... |
567 |
} |
508df92d1 ACPI: battery: re... |
568 569 |
device_remove_file(battery->bat.dev, &alarm_attr); power_supply_unregister(&battery->bat); |
9104476e4 ACPI: Battery: re... |
570 |
battery->bat.dev = NULL; |
69d94ec6d Battery: sysfs_re... |
571 |
mutex_unlock(&battery->sysfs_lock); |
bc76f90b8 ACPI battery: wor... |
572 |
} |
557d58687 ACPI battery: sup... |
573 574 575 576 577 578 579 580 581 582 583 584 |
/* * 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... |
585 |
static void acpi_battery_quirks(struct acpi_battery *battery) |
557d58687 ACPI battery: sup... |
586 587 588 589 590 591 592 593 594 595 596 597 598 |
{ if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)) return ; if (battery->full_charge_capacity == 100 && battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN && battery->capacity_now >=0 && battery->capacity_now <= 100) { 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; } } |
f1d4661ab ACPI: Battery: si... |
599 |
static int acpi_battery_update(struct acpi_battery *battery) |
b6ce4083e ACPI: Cache batte... |
600 |
{ |
50b178512 Newly inserted ba... |
601 |
int result, old_present = acpi_battery_present(battery); |
97749cd9a ACPI: Make sysfs ... |
602 |
result = acpi_battery_get_status(battery); |
508df92d1 ACPI: battery: re... |
603 |
if (result) |
b6ce4083e ACPI: Cache batte... |
604 |
return result; |
508df92d1 ACPI: battery: re... |
605 606 |
if (!acpi_battery_present(battery)) { sysfs_remove_battery(battery); |
97749cd9a ACPI: Make sysfs ... |
607 |
battery->update_time = 0; |
508df92d1 ACPI: battery: re... |
608 |
return 0; |
b6ce4083e ACPI: Cache batte... |
609 |
} |
50b178512 Newly inserted ba... |
610 611 |
if (!battery->update_time || old_present != acpi_battery_present(battery)) { |
97749cd9a ACPI: Make sysfs ... |
612 613 614 615 616 |
result = acpi_battery_get_info(battery); if (result) return result; acpi_battery_init_alarm(battery); } |
eb03cb02b ACPI / Battery: p... |
617 618 619 620 621 |
if (!battery->bat.dev) { result = sysfs_add_battery(battery); if (result) return result; } |
557d58687 ACPI battery: sup... |
622 |
result = acpi_battery_get_state(battery); |
7b78622d0 ACPI / Battery: R... |
623 |
acpi_battery_quirks(battery); |
557d58687 ACPI battery: sup... |
624 |
return result; |
4bd35cdb1 ACPI: battery: ch... |
625 |
} |
da8aeb92d ACPI / Battery: U... |
626 627 628 629 630 631 632 633 634 635 |
static void acpi_battery_refresh(struct acpi_battery *battery) { if (!battery->bat.dev) return; acpi_battery_get_info(battery); /* The battery may have changed its reporting units. */ sysfs_remove_battery(battery); sysfs_add_battery(battery); } |
1da177e4c Linux-2.6.12-rc2 |
636 637 638 |
/* -------------------------------------------------------------------------- FS Interface (/proc) -------------------------------------------------------------------------- */ |
fdcedbba2 ACPI: Split out c... |
639 |
#ifdef CONFIG_ACPI_PROCFS_POWER |
4be44fcd3 [ACPI] Lindent al... |
640 |
static struct proc_dir_entry *acpi_battery_dir; |
b6ce4083e ACPI: Cache batte... |
641 |
|
78490d821 ACPI: battery: sy... |
642 |
static int acpi_battery_print_info(struct seq_file *seq, int result) |
1da177e4c Linux-2.6.12-rc2 |
643 |
{ |
50dd09697 ACPI: Remove unne... |
644 |
struct acpi_battery *battery = seq->private; |
1da177e4c Linux-2.6.12-rc2 |
645 |
|
b6ce4083e ACPI: Cache batte... |
646 |
if (result) |
1da177e4c Linux-2.6.12-rc2 |
647 |
goto end; |
aa650bbdc ACPI: Battery: Mi... |
648 649 650 651 |
seq_printf(seq, "present: %s ", acpi_battery_present(battery)?"yes":"no"); if (!acpi_battery_present(battery)) |
1da177e4c Linux-2.6.12-rc2 |
652 |
goto end; |
038fdea29 ACPI: Battery: do... |
653 |
if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) |
1da177e4c Linux-2.6.12-rc2 |
654 655 656 657 658 |
seq_printf(seq, "design capacity: unknown "); else seq_printf(seq, "design capacity: %d %sh ", |
aa650bbdc ACPI: Battery: Mi... |
659 660 |
battery->design_capacity, acpi_battery_units(battery)); |
1da177e4c Linux-2.6.12-rc2 |
661 |
|
d73809657 ACPI: Battery: Ad... |
662 |
if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN) |
1da177e4c Linux-2.6.12-rc2 |
663 664 665 666 667 |
seq_printf(seq, "last full capacity: unknown "); else seq_printf(seq, "last full capacity: %d %sh ", |
d73809657 ACPI: Battery: Ad... |
668 |
battery->full_charge_capacity, |
aa650bbdc ACPI: Battery: Mi... |
669 670 671 672 673 |
acpi_battery_units(battery)); seq_printf(seq, "battery technology: %srechargeable ", (!battery->technology)?"non-":""); |
1da177e4c Linux-2.6.12-rc2 |
674 |
|
038fdea29 ACPI: Battery: do... |
675 |
if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) |
1da177e4c Linux-2.6.12-rc2 |
676 677 678 679 680 |
seq_printf(seq, "design voltage: unknown "); else seq_printf(seq, "design voltage: %d mV ", |
aa650bbdc ACPI: Battery: Mi... |
681 |
battery->design_voltage); |
1da177e4c Linux-2.6.12-rc2 |
682 683 |
seq_printf(seq, "design capacity warning: %d %sh ", |
aa650bbdc ACPI: Battery: Mi... |
684 685 |
battery->design_capacity_warning, acpi_battery_units(battery)); |
1da177e4c Linux-2.6.12-rc2 |
686 687 |
seq_printf(seq, "design capacity low: %d %sh ", |
aa650bbdc ACPI: Battery: Mi... |
688 689 |
battery->design_capacity_low, acpi_battery_units(battery)); |
c67fcd670 ACPI: Battery: Ad... |
690 691 |
seq_printf(seq, "cycle count: %i ", battery->cycle_count); |
1da177e4c Linux-2.6.12-rc2 |
692 693 |
seq_printf(seq, "capacity granularity 1: %d %sh ", |
aa650bbdc ACPI: Battery: Mi... |
694 695 |
battery->capacity_granularity_1, acpi_battery_units(battery)); |
1da177e4c Linux-2.6.12-rc2 |
696 697 |
seq_printf(seq, "capacity granularity 2: %d %sh ", |
aa650bbdc ACPI: Battery: Mi... |
698 699 |
battery->capacity_granularity_2, acpi_battery_units(battery)); |
038fdea29 ACPI: Battery: do... |
700 701 702 703 704 705 706 707 |
seq_printf(seq, "model number: %s ", battery->model_number); seq_printf(seq, "serial number: %s ", battery->serial_number); seq_printf(seq, "battery type: %s ", battery->type); seq_printf(seq, "OEM info: %s ", battery->oem_info); |
4be44fcd3 [ACPI] Lindent al... |
708 |
end: |
b6ce4083e ACPI: Cache batte... |
709 710 711 |
if (result) seq_printf(seq, "ERROR: Unable to read battery info "); |
b6ce4083e ACPI: Cache batte... |
712 713 |
return result; } |
78490d821 ACPI: battery: sy... |
714 |
static int acpi_battery_print_state(struct seq_file *seq, int result) |
1da177e4c Linux-2.6.12-rc2 |
715 |
{ |
50dd09697 ACPI: Remove unne... |
716 |
struct acpi_battery *battery = seq->private; |
1da177e4c Linux-2.6.12-rc2 |
717 |
|
b6ce4083e ACPI: Cache batte... |
718 |
if (result) |
1da177e4c Linux-2.6.12-rc2 |
719 |
goto end; |
aa650bbdc ACPI: Battery: Mi... |
720 721 722 723 |
seq_printf(seq, "present: %s ", acpi_battery_present(battery)?"yes":"no"); if (!acpi_battery_present(battery)) |
1da177e4c Linux-2.6.12-rc2 |
724 |
goto end; |
b6ce4083e ACPI: Cache batte... |
725 |
|
aa650bbdc ACPI: Battery: Mi... |
726 727 728 729 |
seq_printf(seq, "capacity state: %s ", (battery->state & 0x04)?"critical":"ok"); if ((battery->state & 0x01) && (battery->state & 0x02)) |
4be44fcd3 [ACPI] Lindent al... |
730 731 732 |
seq_printf(seq, "charging state: charging/discharging "); |
aa650bbdc ACPI: Battery: Mi... |
733 |
else if (battery->state & 0x01) |
1da177e4c Linux-2.6.12-rc2 |
734 735 |
seq_printf(seq, "charging state: discharging "); |
038fdea29 ACPI: Battery: do... |
736 |
else if (battery->state & 0x02) |
1da177e4c Linux-2.6.12-rc2 |
737 738 |
seq_printf(seq, "charging state: charging "); |
aa650bbdc ACPI: Battery: Mi... |
739 |
else |
1da177e4c Linux-2.6.12-rc2 |
740 741 |
seq_printf(seq, "charging state: charged "); |
1da177e4c Linux-2.6.12-rc2 |
742 |
|
7faa144a5 ACPI: battery: ad... |
743 |
if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN) |
1da177e4c Linux-2.6.12-rc2 |
744 745 746 747 748 |
seq_printf(seq, "present rate: unknown "); else seq_printf(seq, "present rate: %d %s ", |
7faa144a5 ACPI: battery: ad... |
749 |
battery->rate_now, acpi_battery_units(battery)); |
1da177e4c Linux-2.6.12-rc2 |
750 |
|
d73809657 ACPI: Battery: Ad... |
751 |
if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN) |
1da177e4c Linux-2.6.12-rc2 |
752 753 754 755 756 |
seq_printf(seq, "remaining capacity: unknown "); else seq_printf(seq, "remaining capacity: %d %sh ", |
d73809657 ACPI: Battery: Ad... |
757 758 |
battery->capacity_now, acpi_battery_units(battery)); if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN) |
1da177e4c Linux-2.6.12-rc2 |
759 760 761 762 763 |
seq_printf(seq, "present voltage: unknown "); else seq_printf(seq, "present voltage: %d mV ", |
d73809657 ACPI: Battery: Ad... |
764 |
battery->voltage_now); |
4be44fcd3 [ACPI] Lindent al... |
765 |
end: |
aa650bbdc ACPI: Battery: Mi... |
766 |
if (result) |
b6ce4083e ACPI: Cache batte... |
767 768 |
seq_printf(seq, "ERROR: Unable to read battery state "); |
b6ce4083e ACPI: Cache batte... |
769 770 771 |
return result; } |
78490d821 ACPI: battery: sy... |
772 |
static int acpi_battery_print_alarm(struct seq_file *seq, int result) |
1da177e4c Linux-2.6.12-rc2 |
773 |
{ |
50dd09697 ACPI: Remove unne... |
774 |
struct acpi_battery *battery = seq->private; |
1da177e4c Linux-2.6.12-rc2 |
775 |
|
b6ce4083e ACPI: Cache batte... |
776 |
if (result) |
1da177e4c Linux-2.6.12-rc2 |
777 |
goto end; |
b6ce4083e ACPI: Cache batte... |
778 |
if (!acpi_battery_present(battery)) { |
1da177e4c Linux-2.6.12-rc2 |
779 780 781 782 |
seq_printf(seq, "present: no "); goto end; } |
1da177e4c Linux-2.6.12-rc2 |
783 784 785 786 787 |
seq_printf(seq, "alarm: "); if (!battery->alarm) seq_printf(seq, "unsupported "); else |
aa650bbdc ACPI: Battery: Mi... |
788 789 790 |
seq_printf(seq, "%u %sh ", battery->alarm, acpi_battery_units(battery)); |
4be44fcd3 [ACPI] Lindent al... |
791 |
end: |
b6ce4083e ACPI: Cache batte... |
792 793 794 |
if (result) seq_printf(seq, "ERROR: Unable to read battery alarm "); |
b6ce4083e ACPI: Cache batte... |
795 796 |
return result; } |
f1d4661ab ACPI: Battery: si... |
797 798 799 |
static ssize_t acpi_battery_write_alarm(struct file *file, const char __user * buffer, size_t count, loff_t * ppos) |
1da177e4c Linux-2.6.12-rc2 |
800 |
{ |
4be44fcd3 [ACPI] Lindent al... |
801 802 |
int result = 0; char alarm_string[12] = { '\0' }; |
50dd09697 ACPI: Remove unne... |
803 804 |
struct seq_file *m = file->private_data; struct acpi_battery *battery = m->private; |
1da177e4c Linux-2.6.12-rc2 |
805 |
|
1da177e4c Linux-2.6.12-rc2 |
806 |
if (!battery || (count > sizeof(alarm_string) - 1)) |
d550d98d3 ACPI: delete trac... |
807 |
return -EINVAL; |
b6ce4083e ACPI: Cache batte... |
808 809 810 811 |
if (!acpi_battery_present(battery)) { result = -ENODEV; goto end; } |
b6ce4083e ACPI: Cache batte... |
812 813 814 815 |
if (copy_from_user(alarm_string, buffer, count)) { result = -EFAULT; goto end; } |
1da177e4c Linux-2.6.12-rc2 |
816 |
alarm_string[count] = '\0'; |
f1d4661ab ACPI: Battery: si... |
817 |
battery->alarm = simple_strtol(alarm_string, NULL, 0); |
aa650bbdc ACPI: Battery: Mi... |
818 |
result = acpi_battery_set_alarm(battery); |
b6ce4083e ACPI: Cache batte... |
819 |
end: |
b6ce4083e ACPI: Cache batte... |
820 |
if (!result) |
f1d4661ab ACPI: Battery: si... |
821 |
return count; |
78490d821 ACPI: battery: sy... |
822 823 824 825 |
return result; } typedef int(*print_func)(struct seq_file *seq, int result); |
aa650bbdc ACPI: Battery: Mi... |
826 827 828 829 830 |
static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = { acpi_battery_print_info, acpi_battery_print_state, acpi_battery_print_alarm, |
78490d821 ACPI: battery: sy... |
831 |
}; |
b6ce4083e ACPI: Cache batte... |
832 |
|
78490d821 ACPI: battery: sy... |
833 834 835 |
static int acpi_battery_read(int fid, struct seq_file *seq) { struct acpi_battery *battery = seq->private; |
f1d4661ab ACPI: Battery: si... |
836 |
int result = acpi_battery_update(battery); |
aa650bbdc ACPI: Battery: Mi... |
837 |
return acpi_print_funcs[fid](seq, result); |
78490d821 ACPI: battery: sy... |
838 |
} |
aa650bbdc ACPI: Battery: Mi... |
839 840 841 842 843 844 845 846 |
#define DECLARE_FILE_FUNCTIONS(_name) \ static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \ { \ return acpi_battery_read(_name##_tag, seq); \ } \ static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \ { \ return single_open(file, acpi_battery_read_##_name, PDE(inode)->data); \ |
78490d821 ACPI: battery: sy... |
847 |
} |
aa650bbdc ACPI: Battery: Mi... |
848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 |
DECLARE_FILE_FUNCTIONS(info); DECLARE_FILE_FUNCTIONS(state); DECLARE_FILE_FUNCTIONS(alarm); #undef DECLARE_FILE_FUNCTIONS #define FILE_DESCRIPTION_RO(_name) \ { \ .name = __stringify(_name), \ .mode = S_IRUGO, \ .ops = { \ .open = acpi_battery_##_name##_open_fs, \ .read = seq_read, \ .llseek = seq_lseek, \ .release = single_release, \ .owner = THIS_MODULE, \ }, \ } |
78490d821 ACPI: battery: sy... |
866 |
|
aa650bbdc ACPI: Battery: Mi... |
867 868 869 870 871 872 873 874 875 876 877 878 879 |
#define FILE_DESCRIPTION_RW(_name) \ { \ .name = __stringify(_name), \ .mode = S_IFREG | S_IRUGO | S_IWUSR, \ .ops = { \ .open = acpi_battery_##_name##_open_fs, \ .read = seq_read, \ .llseek = seq_lseek, \ .write = acpi_battery_write_##_name, \ .release = single_release, \ .owner = THIS_MODULE, \ }, \ } |
1da177e4c Linux-2.6.12-rc2 |
880 |
|
9c8b04be4 ACPI: constify op... |
881 |
static const struct battery_file { |
78490d821 ACPI: battery: sy... |
882 |
struct file_operations ops; |
d161a13f9 switch procfs to ... |
883 |
umode_t mode; |
070d8eb1f ACPI: constify VF... |
884 |
const char *name; |
78490d821 ACPI: battery: sy... |
885 |
} acpi_battery_file[] = { |
aa650bbdc ACPI: Battery: Mi... |
886 887 888 |
FILE_DESCRIPTION_RO(info), FILE_DESCRIPTION_RO(state), FILE_DESCRIPTION_RW(alarm), |
1da177e4c Linux-2.6.12-rc2 |
889 |
}; |
aa650bbdc ACPI: Battery: Mi... |
890 891 |
#undef FILE_DESCRIPTION_RO #undef FILE_DESCRIPTION_RW |
4be44fcd3 [ACPI] Lindent al... |
892 |
static int acpi_battery_add_fs(struct acpi_device *device) |
1da177e4c Linux-2.6.12-rc2 |
893 |
{ |
4be44fcd3 [ACPI] Lindent al... |
894 |
struct proc_dir_entry *entry = NULL; |
78490d821 ACPI: battery: sy... |
895 |
int i; |
1da177e4c Linux-2.6.12-rc2 |
896 |
|
6d855fcdd ACPI: delete CONF... |
897 898 899 |
printk(KERN_WARNING PREFIX "Deprecated procfs I/F for battery is loaded," " please retry with CONFIG_ACPI_PROCFS_POWER cleared "); |
1da177e4c Linux-2.6.12-rc2 |
900 901 |
if (!acpi_device_dir(device)) { acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), |
4be44fcd3 [ACPI] Lindent al... |
902 |
acpi_battery_dir); |
1da177e4c Linux-2.6.12-rc2 |
903 |
if (!acpi_device_dir(device)) |
d550d98d3 ACPI: delete trac... |
904 |
return -ENODEV; |
1da177e4c Linux-2.6.12-rc2 |
905 |
} |
78490d821 ACPI: battery: sy... |
906 |
for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) { |
cf7acfab0 acpi: use non-rac... |
907 908 909 910 911 |
entry = proc_create_data(acpi_battery_file[i].name, acpi_battery_file[i].mode, acpi_device_dir(device), &acpi_battery_file[i].ops, acpi_driver_data(device)); |
78490d821 ACPI: battery: sy... |
912 913 |
if (!entry) return -ENODEV; |
1da177e4c Linux-2.6.12-rc2 |
914 |
} |
d550d98d3 ACPI: delete trac... |
915 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
916 |
} |
aa650bbdc ACPI: Battery: Mi... |
917 |
static void acpi_battery_remove_fs(struct acpi_device *device) |
1da177e4c Linux-2.6.12-rc2 |
918 |
{ |
78490d821 ACPI: battery: sy... |
919 |
int i; |
aa650bbdc ACPI: Battery: Mi... |
920 921 922 923 |
if (!acpi_device_dir(device)) return; for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) remove_proc_entry(acpi_battery_file[i].name, |
1da177e4c Linux-2.6.12-rc2 |
924 |
acpi_device_dir(device)); |
1da177e4c Linux-2.6.12-rc2 |
925 |
|
aa650bbdc ACPI: Battery: Mi... |
926 927 |
remove_proc_entry(acpi_device_bid(device), acpi_battery_dir); acpi_device_dir(device) = NULL; |
1da177e4c Linux-2.6.12-rc2 |
928 |
} |
d73809657 ACPI: Battery: Ad... |
929 |
#endif |
3e58ea0d3 ACPI: Battery: ad... |
930 |
|
1da177e4c Linux-2.6.12-rc2 |
931 932 933 |
/* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */ |
d94066910 ACPI: battery: us... |
934 |
static void acpi_battery_notify(struct acpi_device *device, u32 event) |
1da177e4c Linux-2.6.12-rc2 |
935 |
{ |
d94066910 ACPI: battery: us... |
936 |
struct acpi_battery *battery = acpi_driver_data(device); |
153e500f5 ACPI battery: don... |
937 |
struct device *old; |
d94066910 ACPI: battery: us... |
938 |
|
1da177e4c Linux-2.6.12-rc2 |
939 |
if (!battery) |
d550d98d3 ACPI: delete trac... |
940 |
return; |
153e500f5 ACPI battery: don... |
941 |
old = battery->bat.dev; |
da8aeb92d ACPI / Battery: U... |
942 943 |
if (event == ACPI_BATTERY_NOTIFY_INFO) acpi_battery_refresh(battery); |
f1d4661ab ACPI: Battery: si... |
944 945 946 947 |
acpi_battery_update(battery); acpi_bus_generate_proc_event(device, event, acpi_battery_present(battery)); acpi_bus_generate_netlink_event(device->pnp.device_class, |
0794469da ACPI: struct devi... |
948 |
dev_name(&device->dev), event, |
9ea7d5757 ACPI: battery: Li... |
949 |
acpi_battery_present(battery)); |
2345baf4a battery: fix typo... |
950 |
/* acpi_battery_update could remove power_supply object */ |
153e500f5 ACPI battery: don... |
951 |
if (old && battery->bat.dev) |
f79e1cec8 ACPI: battery dri... |
952 |
power_supply_changed(&battery->bat); |
1da177e4c Linux-2.6.12-rc2 |
953 |
} |
25be58215 ACPI battery: fri... |
954 955 956 957 958 959 |
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); switch (mode) { |
d5a5911b3 ACPI / Battery: A... |
960 |
case PM_POST_HIBERNATION: |
25be58215 ACPI battery: fri... |
961 |
case PM_POST_SUSPEND: |
6e17fb6aa ACPI / Battery: A... |
962 963 964 965 |
if (battery->bat.dev) { sysfs_remove_battery(battery); sysfs_add_battery(battery); } |
25be58215 ACPI battery: fri... |
966 967 968 969 970 |
break; } return 0; } |
4be44fcd3 [ACPI] Lindent al... |
971 |
static int acpi_battery_add(struct acpi_device *device) |
1da177e4c Linux-2.6.12-rc2 |
972 |
{ |
4be44fcd3 [ACPI] Lindent al... |
973 |
int result = 0; |
4be44fcd3 [ACPI] Lindent al... |
974 |
struct acpi_battery *battery = NULL; |
c67fcd670 ACPI: Battery: Ad... |
975 |
acpi_handle handle; |
1da177e4c Linux-2.6.12-rc2 |
976 |
if (!device) |
d550d98d3 ACPI: delete trac... |
977 |
return -EINVAL; |
36bcbec7c ACPI: replace kma... |
978 |
battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
979 |
if (!battery) |
d550d98d3 ACPI: delete trac... |
980 |
return -ENOMEM; |
145def84a ACPI: battery: ad... |
981 |
battery->device = device; |
1da177e4c Linux-2.6.12-rc2 |
982 983 |
strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); |
db89b4f0d ACPI: catch calls... |
984 |
device->driver_data = battery; |
038fdea29 ACPI: Battery: do... |
985 |
mutex_init(&battery->lock); |
69d94ec6d Battery: sysfs_re... |
986 |
mutex_init(&battery->sysfs_lock); |
c67fcd670 ACPI: Battery: Ad... |
987 988 989 |
if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle, "_BIX", &handle))) set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); |
eb03cb02b ACPI / Battery: p... |
990 991 992 |
result = acpi_battery_update(battery); if (result) goto fail; |
fdcedbba2 ACPI: Split out c... |
993 |
#ifdef CONFIG_ACPI_PROCFS_POWER |
1da177e4c Linux-2.6.12-rc2 |
994 |
result = acpi_battery_add_fs(device); |
d73809657 ACPI: Battery: Ad... |
995 |
#endif |
e80bba4b5 ACPI / Battery: a... |
996 |
if (result) { |
fdcedbba2 ACPI: Split out c... |
997 |
#ifdef CONFIG_ACPI_PROCFS_POWER |
1da177e4c Linux-2.6.12-rc2 |
998 |
acpi_battery_remove_fs(device); |
d73809657 ACPI: Battery: Ad... |
999 |
#endif |
e80bba4b5 ACPI / Battery: a... |
1000 |
goto fail; |
1da177e4c Linux-2.6.12-rc2 |
1001 |
} |
25be58215 ACPI battery: fri... |
1002 |
|
e80bba4b5 ACPI / Battery: a... |
1003 1004 1005 1006 |
printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s) ", ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), device->status.battery_present ? "present" : "absent"); |
25be58215 ACPI battery: fri... |
1007 1008 |
battery->pm_nb.notifier_call = battery_notify; register_pm_notifier(&battery->pm_nb); |
d550d98d3 ACPI: delete trac... |
1009 |
return result; |
e80bba4b5 ACPI / Battery: a... |
1010 1011 1012 1013 |
fail: sysfs_remove_battery(battery); mutex_destroy(&battery->lock); |
69d94ec6d Battery: sysfs_re... |
1014 |
mutex_destroy(&battery->sysfs_lock); |
e80bba4b5 ACPI / Battery: a... |
1015 1016 |
kfree(battery); return result; |
1da177e4c Linux-2.6.12-rc2 |
1017 |
} |
4be44fcd3 [ACPI] Lindent al... |
1018 |
static int acpi_battery_remove(struct acpi_device *device, int type) |
1da177e4c Linux-2.6.12-rc2 |
1019 |
{ |
4be44fcd3 [ACPI] Lindent al... |
1020 |
struct acpi_battery *battery = NULL; |
1da177e4c Linux-2.6.12-rc2 |
1021 |
|
1da177e4c Linux-2.6.12-rc2 |
1022 |
if (!device || !acpi_driver_data(device)) |
d550d98d3 ACPI: delete trac... |
1023 |
return -EINVAL; |
50dd09697 ACPI: Remove unne... |
1024 |
battery = acpi_driver_data(device); |
25be58215 ACPI battery: fri... |
1025 |
unregister_pm_notifier(&battery->pm_nb); |
fdcedbba2 ACPI: Split out c... |
1026 |
#ifdef CONFIG_ACPI_PROCFS_POWER |
1da177e4c Linux-2.6.12-rc2 |
1027 |
acpi_battery_remove_fs(device); |
d73809657 ACPI: Battery: Ad... |
1028 |
#endif |
508df92d1 ACPI: battery: re... |
1029 |
sysfs_remove_battery(battery); |
038fdea29 ACPI: Battery: do... |
1030 |
mutex_destroy(&battery->lock); |
69d94ec6d Battery: sysfs_re... |
1031 |
mutex_destroy(&battery->sysfs_lock); |
1da177e4c Linux-2.6.12-rc2 |
1032 |
kfree(battery); |
d550d98d3 ACPI: delete trac... |
1033 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
1034 |
} |
34c4415ab ACPI: check batte... |
1035 |
/* this is needed to learn about changes made in suspended state */ |
5d9464a46 ACPI: add ACPI bu... |
1036 |
static int acpi_battery_resume(struct acpi_device *device) |
34c4415ab ACPI: check batte... |
1037 1038 |
{ struct acpi_battery *battery; |
34c4415ab ACPI: check batte... |
1039 1040 |
if (!device) return -EINVAL; |
f1d4661ab ACPI: Battery: si... |
1041 1042 |
battery = acpi_driver_data(device); battery->update_time = 0; |
508df92d1 ACPI: battery: re... |
1043 |
acpi_battery_update(battery); |
b6ce4083e ACPI: Cache batte... |
1044 |
return 0; |
34c4415ab ACPI: check batte... |
1045 |
} |
aa650bbdc ACPI: Battery: Mi... |
1046 1047 1048 1049 |
static struct acpi_driver acpi_battery_driver = { .name = "battery", .class = ACPI_BATTERY_CLASS, .ids = battery_device_ids, |
d94066910 ACPI: battery: us... |
1050 |
.flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, |
aa650bbdc ACPI: Battery: Mi... |
1051 1052 1053 1054 |
.ops = { .add = acpi_battery_add, .resume = acpi_battery_resume, .remove = acpi_battery_remove, |
d94066910 ACPI: battery: us... |
1055 |
.notify = acpi_battery_notify, |
aa650bbdc ACPI: Battery: Mi... |
1056 1057 |
}, }; |
b0cbc861a Revert "ACPI batt... |
1058 |
static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie) |
1da177e4c Linux-2.6.12-rc2 |
1059 |
{ |
4d8316d5e ACPI: fix boot wi... |
1060 |
if (acpi_disabled) |
0f66af530 ACPI: battery: as... |
1061 |
return; |
fdcedbba2 ACPI: Split out c... |
1062 |
#ifdef CONFIG_ACPI_PROCFS_POWER |
3f86b8324 ACPI: add support... |
1063 |
acpi_battery_dir = acpi_lock_battery_dir(); |
1da177e4c Linux-2.6.12-rc2 |
1064 |
if (!acpi_battery_dir) |
0f66af530 ACPI: battery: as... |
1065 |
return; |
d73809657 ACPI: Battery: Ad... |
1066 |
#endif |
aa650bbdc ACPI: Battery: Mi... |
1067 |
if (acpi_bus_register_driver(&acpi_battery_driver) < 0) { |
fdcedbba2 ACPI: Split out c... |
1068 |
#ifdef CONFIG_ACPI_PROCFS_POWER |
3f86b8324 ACPI: add support... |
1069 |
acpi_unlock_battery_dir(acpi_battery_dir); |
d73809657 ACPI: Battery: Ad... |
1070 |
#endif |
0f66af530 ACPI: battery: as... |
1071 |
return; |
1da177e4c Linux-2.6.12-rc2 |
1072 |
} |
0f66af530 ACPI: battery: as... |
1073 1074 1075 1076 1077 1078 |
return; } static int __init acpi_battery_init(void) { async_schedule(acpi_battery_init_async, NULL); |
d550d98d3 ACPI: delete trac... |
1079 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
1080 |
} |
4be44fcd3 [ACPI] Lindent al... |
1081 |
static void __exit acpi_battery_exit(void) |
1da177e4c Linux-2.6.12-rc2 |
1082 |
{ |
1da177e4c Linux-2.6.12-rc2 |
1083 |
acpi_bus_unregister_driver(&acpi_battery_driver); |
fdcedbba2 ACPI: Split out c... |
1084 |
#ifdef CONFIG_ACPI_PROCFS_POWER |
3f86b8324 ACPI: add support... |
1085 |
acpi_unlock_battery_dir(acpi_battery_dir); |
d73809657 ACPI: Battery: Ad... |
1086 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
1087 |
} |
1da177e4c Linux-2.6.12-rc2 |
1088 1089 |
module_init(acpi_battery_init); module_exit(acpi_battery_exit); |