diff options
-rw-r--r-- | drivers/acpi/battery.c | 359 |
1 files changed, 139 insertions, 220 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 9b2c0f74f869..de506f39d3bd 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -36,9 +36,6 @@ | |||
36 | 36 | ||
37 | #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF | 37 | #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF |
38 | 38 | ||
39 | #define ACPI_BATTERY_FORMAT_BIF "NNNNNNNNNSSSS" | ||
40 | #define ACPI_BATTERY_FORMAT_BST "NNNN" | ||
41 | |||
42 | #define ACPI_BATTERY_COMPONENT 0x00040000 | 39 | #define ACPI_BATTERY_COMPONENT 0x00040000 |
43 | #define ACPI_BATTERY_CLASS "battery" | 40 | #define ACPI_BATTERY_CLASS "battery" |
44 | #define ACPI_BATTERY_DEVICE_NAME "Battery" | 41 | #define ACPI_BATTERY_DEVICE_NAME "Battery" |
@@ -90,61 +87,49 @@ static struct acpi_driver acpi_battery_driver = { | |||
90 | }, | 87 | }, |
91 | }; | 88 | }; |
92 | 89 | ||
93 | struct acpi_battery_state { | 90 | enum acpi_battery_files { |
94 | acpi_integer state; | ||
95 | acpi_integer present_rate; | ||
96 | acpi_integer remaining_capacity; | ||
97 | acpi_integer present_voltage; | ||
98 | }; | ||
99 | |||
100 | struct acpi_battery_info { | ||
101 | acpi_integer power_unit; | ||
102 | acpi_integer design_capacity; | ||
103 | acpi_integer last_full_capacity; | ||
104 | acpi_integer battery_technology; | ||
105 | acpi_integer design_voltage; | ||
106 | acpi_integer design_capacity_warning; | ||
107 | acpi_integer design_capacity_low; | ||
108 | acpi_integer battery_capacity_granularity_1; | ||
109 | acpi_integer battery_capacity_granularity_2; | ||
110 | acpi_string model_number; | ||
111 | acpi_string serial_number; | ||
112 | acpi_string battery_type; | ||
113 | acpi_string oem_info; | ||
114 | }; | ||
115 | |||
116 | enum acpi_battery_files{ | ||
117 | ACPI_BATTERY_INFO = 0, | 91 | ACPI_BATTERY_INFO = 0, |
118 | ACPI_BATTERY_STATE, | 92 | ACPI_BATTERY_STATE, |
119 | ACPI_BATTERY_ALARM, | 93 | ACPI_BATTERY_ALARM, |
120 | ACPI_BATTERY_NUMFILES, | 94 | ACPI_BATTERY_NUMFILES, |
121 | }; | 95 | }; |
122 | 96 | ||
123 | struct acpi_battery_flags { | ||
124 | u8 battery_present_prev; | ||
125 | u8 alarm_present; | ||
126 | u8 init_update; | ||
127 | u8 update[ACPI_BATTERY_NUMFILES]; | ||
128 | u8 power_unit; | ||
129 | }; | ||
130 | |||
131 | struct acpi_battery { | 97 | struct acpi_battery { |
132 | struct mutex mutex; | ||
133 | struct acpi_device *device; | 98 | struct acpi_device *device; |
134 | struct acpi_battery_flags flags; | 99 | struct mutex lock; |
135 | struct acpi_buffer bif_data; | ||
136 | struct acpi_buffer bst_data; | ||
137 | unsigned long alarm; | 100 | unsigned long alarm; |
138 | unsigned long update_time[ACPI_BATTERY_NUMFILES]; | 101 | unsigned long update_time[ACPI_BATTERY_NUMFILES]; |
102 | int state; | ||
103 | int present_rate; | ||
104 | int remaining_capacity; | ||
105 | int present_voltage; | ||
106 | int power_unit; | ||
107 | int design_capacity; | ||
108 | int last_full_capacity; | ||
109 | int technology; | ||
110 | int design_voltage; | ||
111 | int design_capacity_warning; | ||
112 | int design_capacity_low; | ||
113 | int capacity_granularity_1; | ||
114 | int capacity_granularity_2; | ||
115 | char model_number[32]; | ||
116 | char serial_number[32]; | ||
117 | char type[32]; | ||
118 | char oem_info[32]; | ||
119 | u8 present_prev; | ||
120 | u8 alarm_present; | ||
121 | u8 init_update; | ||
122 | u8 update[ACPI_BATTERY_NUMFILES]; | ||
139 | }; | 123 | }; |
140 | 124 | ||
141 | inline int acpi_battery_present(struct acpi_battery *battery) | 125 | inline int acpi_battery_present(struct acpi_battery *battery) |
142 | { | 126 | { |
143 | return battery->device->status.battery_present; | 127 | return battery->device->status.battery_present; |
144 | } | 128 | } |
129 | |||
145 | inline char *acpi_battery_power_units(struct acpi_battery *battery) | 130 | inline char *acpi_battery_power_units(struct acpi_battery *battery) |
146 | { | 131 | { |
147 | if (battery->flags.power_unit) | 132 | if (battery->power_unit) |
148 | return ACPI_BATTERY_UNITS_AMPS; | 133 | return ACPI_BATTERY_UNITS_AMPS; |
149 | else | 134 | else |
150 | return ACPI_BATTERY_UNITS_WATTS; | 135 | return ACPI_BATTERY_UNITS_WATTS; |
@@ -165,43 +150,63 @@ static void acpi_battery_check_result(struct acpi_battery *battery, int result) | |||
165 | return; | 150 | return; |
166 | 151 | ||
167 | if (result) { | 152 | if (result) { |
168 | battery->flags.init_update = 1; | 153 | battery->init_update = 1; |
169 | } | 154 | } |
170 | } | 155 | } |
171 | 156 | ||
172 | static int acpi_battery_extract_package(struct acpi_battery *battery, | 157 | struct acpi_offsets { |
173 | union acpi_object *package, | 158 | size_t offset; /* offset inside struct acpi_sbs_battery */ |
174 | struct acpi_buffer *format, | 159 | u8 mode; /* int or string? */ |
175 | struct acpi_buffer *data, | 160 | }; |
176 | char *package_name) | ||
177 | { | ||
178 | acpi_status status = AE_OK; | ||
179 | struct acpi_buffer data_null = { 0, NULL }; | ||
180 | 161 | ||
181 | status = acpi_extract_package(package, format, &data_null); | 162 | static struct acpi_offsets state_offsets[] = { |
182 | if (status != AE_BUFFER_OVERFLOW) { | 163 | {offsetof(struct acpi_battery, state), 0}, |
183 | ACPI_EXCEPTION((AE_INFO, status, "Extracting size %s", | 164 | {offsetof(struct acpi_battery, present_rate), 0}, |
184 | package_name)); | 165 | {offsetof(struct acpi_battery, remaining_capacity), 0}, |
185 | return -ENODEV; | 166 | {offsetof(struct acpi_battery, present_voltage), 0}, |
186 | } | 167 | }; |
187 | 168 | ||
188 | if (data_null.length != data->length) { | 169 | static struct acpi_offsets info_offsets[] = { |
189 | kfree(data->pointer); | 170 | {offsetof(struct acpi_battery, power_unit), 0}, |
190 | data->pointer = kzalloc(data_null.length, GFP_KERNEL); | 171 | {offsetof(struct acpi_battery, design_capacity), 0}, |
191 | if (!data->pointer) { | 172 | {offsetof(struct acpi_battery, last_full_capacity), 0}, |
192 | ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "kzalloc()")); | 173 | {offsetof(struct acpi_battery, technology), 0}, |
193 | return -ENOMEM; | 174 | {offsetof(struct acpi_battery, design_voltage), 0}, |
194 | } | 175 | {offsetof(struct acpi_battery, design_capacity_warning), 0}, |
195 | data->length = data_null.length; | 176 | {offsetof(struct acpi_battery, design_capacity_low), 0}, |
196 | } | 177 | {offsetof(struct acpi_battery, capacity_granularity_1), 0}, |
178 | {offsetof(struct acpi_battery, capacity_granularity_2), 0}, | ||
179 | {offsetof(struct acpi_battery, model_number), 1}, | ||
180 | {offsetof(struct acpi_battery, serial_number), 1}, | ||
181 | {offsetof(struct acpi_battery, type), 1}, | ||
182 | {offsetof(struct acpi_battery, oem_info), 1}, | ||
183 | }; | ||
197 | 184 | ||
198 | status = acpi_extract_package(package, format, data); | 185 | static int extract_package(struct acpi_battery *battery, |
199 | if (ACPI_FAILURE(status)) { | 186 | union acpi_object *package, |
200 | ACPI_EXCEPTION((AE_INFO, status, "Extracting %s", | 187 | struct acpi_offsets *offsets, int num) |
201 | package_name)); | 188 | { |
202 | return -ENODEV; | 189 | int i, *x; |
190 | union acpi_object *element; | ||
191 | if (package->type != ACPI_TYPE_PACKAGE) | ||
192 | return -EFAULT; | ||
193 | for (i = 0; i < num; ++i) { | ||
194 | if (package->package.count <= i) | ||
195 | return -EFAULT; | ||
196 | element = &package->package.elements[i]; | ||
197 | if (offsets[i].mode) { | ||
198 | if (element->type != ACPI_TYPE_STRING && | ||
199 | element->type != ACPI_TYPE_BUFFER) | ||
200 | return -EFAULT; | ||
201 | strncpy((u8 *)battery + offsets[i].offset, | ||
202 | element->string.pointer, 32); | ||
203 | } else { | ||
204 | if (element->type != ACPI_TYPE_INTEGER) | ||
205 | return -EFAULT; | ||
206 | x = (int *)((u8 *)battery + offsets[i].offset); | ||
207 | *x = element->integer.value; | ||
208 | } | ||
203 | } | 209 | } |
204 | |||
205 | return 0; | 210 | return 0; |
206 | } | 211 | } |
207 | 212 | ||
@@ -222,49 +227,21 @@ static int acpi_battery_get_info(struct acpi_battery *battery) | |||
222 | int result = 0; | 227 | int result = 0; |
223 | acpi_status status = 0; | 228 | acpi_status status = 0; |
224 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 229 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
225 | struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF), | ||
226 | ACPI_BATTERY_FORMAT_BIF | ||
227 | }; | ||
228 | union acpi_object *package = NULL; | ||
229 | struct acpi_buffer *data = NULL; | ||
230 | struct acpi_battery_info *bif = NULL; | ||
231 | 230 | ||
232 | battery->update_time[ACPI_BATTERY_INFO] = get_seconds(); | 231 | battery->update_time[ACPI_BATTERY_INFO] = get_seconds(); |
233 | |||
234 | if (!acpi_battery_present(battery)) | 232 | if (!acpi_battery_present(battery)) |
235 | return 0; | 233 | return 0; |
236 | 234 | mutex_lock(&battery->lock); | |
237 | /* Evaluate _BIF */ | 235 | status = acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", |
238 | 236 | NULL, &buffer); | |
239 | status = | 237 | mutex_unlock(&battery->lock); |
240 | acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL, | ||
241 | &buffer); | ||
242 | if (ACPI_FAILURE(status)) { | 238 | if (ACPI_FAILURE(status)) { |
243 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); | 239 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); |
244 | return -ENODEV; | 240 | return -ENODEV; |
245 | } | 241 | } |
246 | 242 | result = extract_package(battery, buffer.pointer, | |
247 | package = buffer.pointer; | 243 | info_offsets, ARRAY_SIZE(info_offsets)); |
248 | |||
249 | data = &battery->bif_data; | ||
250 | |||
251 | /* Extract Package Data */ | ||
252 | |||
253 | result = | ||
254 | acpi_battery_extract_package(battery, package, &format, data, | ||
255 | "_BIF"); | ||
256 | if (result) | ||
257 | goto end; | ||
258 | |||
259 | end: | ||
260 | |||
261 | kfree(buffer.pointer); | 244 | kfree(buffer.pointer); |
262 | |||
263 | if (!result) { | ||
264 | bif = data->pointer; | ||
265 | battery->flags.power_unit = bif->power_unit; | ||
266 | } | ||
267 | |||
268 | return result; | 245 | return result; |
269 | } | 246 | } |
270 | 247 | ||
@@ -273,42 +250,24 @@ static int acpi_battery_get_state(struct acpi_battery *battery) | |||
273 | int result = 0; | 250 | int result = 0; |
274 | acpi_status status = 0; | 251 | acpi_status status = 0; |
275 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 252 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
276 | struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST), | ||
277 | ACPI_BATTERY_FORMAT_BST | ||
278 | }; | ||
279 | union acpi_object *package = NULL; | ||
280 | struct acpi_buffer *data = NULL; | ||
281 | 253 | ||
282 | battery->update_time[ACPI_BATTERY_STATE] = get_seconds(); | 254 | battery->update_time[ACPI_BATTERY_STATE] = get_seconds(); |
283 | 255 | ||
284 | if (!acpi_battery_present(battery)) | 256 | if (!acpi_battery_present(battery)) |
285 | return 0; | 257 | return 0; |
286 | 258 | ||
287 | /* Evaluate _BST */ | 259 | mutex_lock(&battery->lock); |
260 | status = acpi_evaluate_object(acpi_battery_handle(battery), "_BST", | ||
261 | NULL, &buffer); | ||
262 | mutex_unlock(&battery->lock); | ||
288 | 263 | ||
289 | status = | ||
290 | acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL, | ||
291 | &buffer); | ||
292 | if (ACPI_FAILURE(status)) { | 264 | if (ACPI_FAILURE(status)) { |
293 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); | 265 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); |
294 | return -ENODEV; | 266 | return -ENODEV; |
295 | } | 267 | } |
296 | 268 | result = extract_package(battery, buffer.pointer, | |
297 | package = buffer.pointer; | 269 | state_offsets, ARRAY_SIZE(state_offsets)); |
298 | |||
299 | data = &battery->bst_data; | ||
300 | |||
301 | /* Extract Package Data */ | ||
302 | |||
303 | result = | ||
304 | acpi_battery_extract_package(battery, package, &format, data, | ||
305 | "_BST"); | ||
306 | if (result) | ||
307 | goto end; | ||
308 | |||
309 | end: | ||
310 | kfree(buffer.pointer); | 270 | kfree(buffer.pointer); |
311 | |||
312 | return result; | 271 | return result; |
313 | } | 272 | } |
314 | 273 | ||
@@ -331,14 +290,15 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery, | |||
331 | if (!acpi_battery_present(battery)) | 290 | if (!acpi_battery_present(battery)) |
332 | return -ENODEV; | 291 | return -ENODEV; |
333 | 292 | ||
334 | if (!battery->flags.alarm_present) | 293 | if (!battery->alarm_present) |
335 | return -ENODEV; | 294 | return -ENODEV; |
336 | 295 | ||
337 | arg0.integer.value = alarm; | 296 | arg0.integer.value = alarm; |
338 | 297 | ||
339 | status = | 298 | mutex_lock(&battery->lock); |
340 | acpi_evaluate_object(acpi_battery_handle(battery), "_BTP", | 299 | status = acpi_evaluate_object(acpi_battery_handle(battery), "_BTP", |
341 | &arg_list, NULL); | 300 | &arg_list, NULL); |
301 | mutex_unlock(&battery->lock); | ||
342 | if (ACPI_FAILURE(status)) | 302 | if (ACPI_FAILURE(status)) |
343 | return -ENODEV; | 303 | return -ENODEV; |
344 | 304 | ||
@@ -354,22 +314,21 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery) | |||
354 | int result = 0; | 314 | int result = 0; |
355 | acpi_status status = AE_OK; | 315 | acpi_status status = AE_OK; |
356 | acpi_handle handle = NULL; | 316 | acpi_handle handle = NULL; |
357 | struct acpi_battery_info *bif = battery->bif_data.pointer; | ||
358 | unsigned long alarm = battery->alarm; | 317 | unsigned long alarm = battery->alarm; |
359 | 318 | ||
360 | /* See if alarms are supported, and if so, set default */ | 319 | /* See if alarms are supported, and if so, set default */ |
361 | 320 | ||
362 | status = acpi_get_handle(acpi_battery_handle(battery), "_BTP", &handle); | 321 | status = acpi_get_handle(acpi_battery_handle(battery), "_BTP", &handle); |
363 | if (ACPI_SUCCESS(status)) { | 322 | if (ACPI_SUCCESS(status)) { |
364 | battery->flags.alarm_present = 1; | 323 | battery->alarm_present = 1; |
365 | if (!alarm && bif) { | 324 | if (!alarm) { |
366 | alarm = bif->design_capacity_warning; | 325 | alarm = battery->design_capacity_warning; |
367 | } | 326 | } |
368 | result = acpi_battery_set_alarm(battery, alarm); | 327 | result = acpi_battery_set_alarm(battery, alarm); |
369 | if (result) | 328 | if (result) |
370 | goto end; | 329 | goto end; |
371 | } else { | 330 | } else { |
372 | battery->flags.alarm_present = 0; | 331 | battery->alarm_present = 0; |
373 | } | 332 | } |
374 | 333 | ||
375 | end: | 334 | end: |
@@ -385,7 +344,7 @@ static int acpi_battery_init_update(struct acpi_battery *battery) | |||
385 | if (result) | 344 | if (result) |
386 | return result; | 345 | return result; |
387 | 346 | ||
388 | battery->flags.battery_present_prev = acpi_battery_present(battery); | 347 | battery->present_prev = acpi_battery_present(battery); |
389 | 348 | ||
390 | if (acpi_battery_present(battery)) { | 349 | if (acpi_battery_present(battery)) { |
391 | result = acpi_battery_get_info(battery); | 350 | result = acpi_battery_get_info(battery); |
@@ -411,7 +370,7 @@ static int acpi_battery_update(struct acpi_battery *battery, | |||
411 | update = 1; | 370 | update = 1; |
412 | } | 371 | } |
413 | 372 | ||
414 | if (battery->flags.init_update) { | 373 | if (battery->init_update) { |
415 | result = acpi_battery_init_update(battery); | 374 | result = acpi_battery_init_update(battery); |
416 | if (result) | 375 | if (result) |
417 | goto end; | 376 | goto end; |
@@ -420,8 +379,8 @@ static int acpi_battery_update(struct acpi_battery *battery, | |||
420 | result = acpi_battery_get_status(battery); | 379 | result = acpi_battery_get_status(battery); |
421 | if (result) | 380 | if (result) |
422 | goto end; | 381 | goto end; |
423 | if ((!battery->flags.battery_present_prev & acpi_battery_present(battery)) | 382 | if ((!battery->present_prev & acpi_battery_present(battery)) |
424 | || (battery->flags.battery_present_prev & !acpi_battery_present(battery))) { | 383 | || (battery->present_prev & !acpi_battery_present(battery))) { |
425 | result = acpi_battery_init_update(battery); | 384 | result = acpi_battery_init_update(battery); |
426 | if (result) | 385 | if (result) |
427 | goto end; | 386 | goto end; |
@@ -433,7 +392,7 @@ static int acpi_battery_update(struct acpi_battery *battery, | |||
433 | 392 | ||
434 | end: | 393 | end: |
435 | 394 | ||
436 | battery->flags.init_update = (result != 0); | 395 | battery->init_update = (result != 0); |
437 | 396 | ||
438 | *update_result_ptr = update_result; | 397 | *update_result_ptr = update_result; |
439 | 398 | ||
@@ -444,19 +403,19 @@ static void acpi_battery_notify_update(struct acpi_battery *battery) | |||
444 | { | 403 | { |
445 | acpi_battery_get_status(battery); | 404 | acpi_battery_get_status(battery); |
446 | 405 | ||
447 | if (battery->flags.init_update) { | 406 | if (battery->init_update) { |
448 | return; | 407 | return; |
449 | } | 408 | } |
450 | 409 | ||
451 | if ((!battery->flags.battery_present_prev & | 410 | if ((!battery->present_prev & |
452 | acpi_battery_present(battery)) || | 411 | acpi_battery_present(battery)) || |
453 | (battery->flags.battery_present_prev & | 412 | (battery->present_prev & |
454 | !acpi_battery_present(battery))) { | 413 | !acpi_battery_present(battery))) { |
455 | battery->flags.init_update = 1; | 414 | battery->init_update = 1; |
456 | } else { | 415 | } else { |
457 | battery->flags.update[ACPI_BATTERY_INFO] = 1; | 416 | battery->update[ACPI_BATTERY_INFO] = 1; |
458 | battery->flags.update[ACPI_BATTERY_STATE] = 1; | 417 | battery->update[ACPI_BATTERY_STATE] = 1; |
459 | battery->flags.update[ACPI_BATTERY_ALARM] = 1; | 418 | battery->update[ACPI_BATTERY_ALARM] = 1; |
460 | } | 419 | } |
461 | } | 420 | } |
462 | 421 | ||
@@ -469,7 +428,6 @@ static struct proc_dir_entry *acpi_battery_dir; | |||
469 | static int acpi_battery_print_info(struct seq_file *seq, int result) | 428 | static int acpi_battery_print_info(struct seq_file *seq, int result) |
470 | { | 429 | { |
471 | struct acpi_battery *battery = seq->private; | 430 | struct acpi_battery *battery = seq->private; |
472 | struct acpi_battery_info *bif = NULL; | ||
473 | char *units = "?"; | 431 | char *units = "?"; |
474 | 432 | ||
475 | if (result) | 433 | if (result) |
@@ -482,30 +440,23 @@ static int acpi_battery_print_info(struct seq_file *seq, int result) | |||
482 | goto end; | 440 | goto end; |
483 | } | 441 | } |
484 | 442 | ||
485 | bif = battery->bif_data.pointer; | ||
486 | if (!bif) { | ||
487 | ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BIF buffer is NULL")); | ||
488 | result = -ENODEV; | ||
489 | goto end; | ||
490 | } | ||
491 | |||
492 | /* Battery Units */ | 443 | /* Battery Units */ |
493 | 444 | ||
494 | units = acpi_battery_power_units(battery); | 445 | units = acpi_battery_power_units(battery); |
495 | 446 | ||
496 | if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) | 447 | if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) |
497 | seq_printf(seq, "design capacity: unknown\n"); | 448 | seq_printf(seq, "design capacity: unknown\n"); |
498 | else | 449 | else |
499 | seq_printf(seq, "design capacity: %d %sh\n", | 450 | seq_printf(seq, "design capacity: %d %sh\n", |
500 | (u32) bif->design_capacity, units); | 451 | (u32) battery->design_capacity, units); |
501 | 452 | ||
502 | if (bif->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN) | 453 | if (battery->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN) |
503 | seq_printf(seq, "last full capacity: unknown\n"); | 454 | seq_printf(seq, "last full capacity: unknown\n"); |
504 | else | 455 | else |
505 | seq_printf(seq, "last full capacity: %d %sh\n", | 456 | seq_printf(seq, "last full capacity: %d %sh\n", |
506 | (u32) bif->last_full_capacity, units); | 457 | (u32) battery->last_full_capacity, units); |
507 | 458 | ||
508 | switch ((u32) bif->battery_technology) { | 459 | switch ((u32) battery->technology) { |
509 | case 0: | 460 | case 0: |
510 | seq_printf(seq, "battery technology: non-rechargeable\n"); | 461 | seq_printf(seq, "battery technology: non-rechargeable\n"); |
511 | break; | 462 | break; |
@@ -517,23 +468,23 @@ static int acpi_battery_print_info(struct seq_file *seq, int result) | |||
517 | break; | 468 | break; |
518 | } | 469 | } |
519 | 470 | ||
520 | if (bif->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) | 471 | if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) |
521 | seq_printf(seq, "design voltage: unknown\n"); | 472 | seq_printf(seq, "design voltage: unknown\n"); |
522 | else | 473 | else |
523 | seq_printf(seq, "design voltage: %d mV\n", | 474 | seq_printf(seq, "design voltage: %d mV\n", |
524 | (u32) bif->design_voltage); | 475 | (u32) battery->design_voltage); |
525 | seq_printf(seq, "design capacity warning: %d %sh\n", | 476 | seq_printf(seq, "design capacity warning: %d %sh\n", |
526 | (u32) bif->design_capacity_warning, units); | 477 | (u32) battery->design_capacity_warning, units); |
527 | seq_printf(seq, "design capacity low: %d %sh\n", | 478 | seq_printf(seq, "design capacity low: %d %sh\n", |
528 | (u32) bif->design_capacity_low, units); | 479 | (u32) battery->design_capacity_low, units); |
529 | seq_printf(seq, "capacity granularity 1: %d %sh\n", | 480 | seq_printf(seq, "capacity granularity 1: %d %sh\n", |
530 | (u32) bif->battery_capacity_granularity_1, units); | 481 | (u32) battery->capacity_granularity_1, units); |
531 | seq_printf(seq, "capacity granularity 2: %d %sh\n", | 482 | seq_printf(seq, "capacity granularity 2: %d %sh\n", |
532 | (u32) bif->battery_capacity_granularity_2, units); | 483 | (u32) battery->capacity_granularity_2, units); |
533 | seq_printf(seq, "model number: %s\n", bif->model_number); | 484 | seq_printf(seq, "model number: %s\n", battery->model_number); |
534 | seq_printf(seq, "serial number: %s\n", bif->serial_number); | 485 | seq_printf(seq, "serial number: %s\n", battery->serial_number); |
535 | seq_printf(seq, "battery type: %s\n", bif->battery_type); | 486 | seq_printf(seq, "battery type: %s\n", battery->type); |
536 | seq_printf(seq, "OEM info: %s\n", bif->oem_info); | 487 | seq_printf(seq, "OEM info: %s\n", battery->oem_info); |
537 | 488 | ||
538 | end: | 489 | end: |
539 | 490 | ||
@@ -546,7 +497,6 @@ static int acpi_battery_print_info(struct seq_file *seq, int result) | |||
546 | static int acpi_battery_print_state(struct seq_file *seq, int result) | 497 | static int acpi_battery_print_state(struct seq_file *seq, int result) |
547 | { | 498 | { |
548 | struct acpi_battery *battery = seq->private; | 499 | struct acpi_battery *battery = seq->private; |
549 | struct acpi_battery_state *bst = NULL; | ||
550 | char *units = "?"; | 500 | char *units = "?"; |
551 | 501 | ||
552 | if (result) | 502 | if (result) |
@@ -559,50 +509,43 @@ static int acpi_battery_print_state(struct seq_file *seq, int result) | |||
559 | goto end; | 509 | goto end; |
560 | } | 510 | } |
561 | 511 | ||
562 | bst = battery->bst_data.pointer; | ||
563 | if (!bst) { | ||
564 | ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BST buffer is NULL")); | ||
565 | result = -ENODEV; | ||
566 | goto end; | ||
567 | } | ||
568 | |||
569 | /* Battery Units */ | 512 | /* Battery Units */ |
570 | 513 | ||
571 | units = acpi_battery_power_units(battery); | 514 | units = acpi_battery_power_units(battery); |
572 | 515 | ||
573 | if (!(bst->state & 0x04)) | 516 | if (!(battery->state & 0x04)) |
574 | seq_printf(seq, "capacity state: ok\n"); | 517 | seq_printf(seq, "capacity state: ok\n"); |
575 | else | 518 | else |
576 | seq_printf(seq, "capacity state: critical\n"); | 519 | seq_printf(seq, "capacity state: critical\n"); |
577 | 520 | ||
578 | if ((bst->state & 0x01) && (bst->state & 0x02)) { | 521 | if ((battery->state & 0x01) && (battery->state & 0x02)) { |
579 | seq_printf(seq, | 522 | seq_printf(seq, |
580 | "charging state: charging/discharging\n"); | 523 | "charging state: charging/discharging\n"); |
581 | } else if (bst->state & 0x01) | 524 | } else if (battery->state & 0x01) |
582 | seq_printf(seq, "charging state: discharging\n"); | 525 | seq_printf(seq, "charging state: discharging\n"); |
583 | else if (bst->state & 0x02) | 526 | else if (battery->state & 0x02) |
584 | seq_printf(seq, "charging state: charging\n"); | 527 | seq_printf(seq, "charging state: charging\n"); |
585 | else { | 528 | else { |
586 | seq_printf(seq, "charging state: charged\n"); | 529 | seq_printf(seq, "charging state: charged\n"); |
587 | } | 530 | } |
588 | 531 | ||
589 | if (bst->present_rate == ACPI_BATTERY_VALUE_UNKNOWN) | 532 | if (battery->present_rate == ACPI_BATTERY_VALUE_UNKNOWN) |
590 | seq_printf(seq, "present rate: unknown\n"); | 533 | seq_printf(seq, "present rate: unknown\n"); |
591 | else | 534 | else |
592 | seq_printf(seq, "present rate: %d %s\n", | 535 | seq_printf(seq, "present rate: %d %s\n", |
593 | (u32) bst->present_rate, units); | 536 | (u32) battery->present_rate, units); |
594 | 537 | ||
595 | if (bst->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN) | 538 | if (battery->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN) |
596 | seq_printf(seq, "remaining capacity: unknown\n"); | 539 | seq_printf(seq, "remaining capacity: unknown\n"); |
597 | else | 540 | else |
598 | seq_printf(seq, "remaining capacity: %d %sh\n", | 541 | seq_printf(seq, "remaining capacity: %d %sh\n", |
599 | (u32) bst->remaining_capacity, units); | 542 | (u32) battery->remaining_capacity, units); |
600 | 543 | ||
601 | if (bst->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN) | 544 | if (battery->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN) |
602 | seq_printf(seq, "present voltage: unknown\n"); | 545 | seq_printf(seq, "present voltage: unknown\n"); |
603 | else | 546 | else |
604 | seq_printf(seq, "present voltage: %d mV\n", | 547 | seq_printf(seq, "present voltage: %d mV\n", |
605 | (u32) bst->present_voltage); | 548 | (u32) battery->present_voltage); |
606 | 549 | ||
607 | end: | 550 | end: |
608 | 551 | ||
@@ -658,8 +601,6 @@ acpi_battery_write_alarm(struct file *file, | |||
658 | if (!battery || (count > sizeof(alarm_string) - 1)) | 601 | if (!battery || (count > sizeof(alarm_string) - 1)) |
659 | return -EINVAL; | 602 | return -EINVAL; |
660 | 603 | ||
661 | mutex_lock(&battery->mutex); | ||
662 | |||
663 | result = acpi_battery_update(battery, 1, &update_result); | 604 | result = acpi_battery_update(battery, 1, &update_result); |
664 | if (result) { | 605 | if (result) { |
665 | result = -ENODEV; | 606 | result = -ENODEV; |
@@ -689,9 +630,6 @@ acpi_battery_write_alarm(struct file *file, | |||
689 | 630 | ||
690 | if (!result) | 631 | if (!result) |
691 | result = count; | 632 | result = count; |
692 | |||
693 | mutex_unlock(&battery->mutex); | ||
694 | |||
695 | return result; | 633 | return result; |
696 | } | 634 | } |
697 | 635 | ||
@@ -714,10 +652,8 @@ static int acpi_battery_read(int fid, struct seq_file *seq) | |||
714 | int update_result = ACPI_BATTERY_NONE_UPDATE; | 652 | int update_result = ACPI_BATTERY_NONE_UPDATE; |
715 | int update = 0; | 653 | int update = 0; |
716 | 654 | ||
717 | mutex_lock(&battery->mutex); | ||
718 | |||
719 | update = (get_seconds() - battery->update_time[fid] >= update_time); | 655 | update = (get_seconds() - battery->update_time[fid] >= update_time); |
720 | update = (update | battery->flags.update[fid]); | 656 | update = (update | battery->update[fid]); |
721 | 657 | ||
722 | result = acpi_battery_update(battery, update, &update_result); | 658 | result = acpi_battery_update(battery, update, &update_result); |
723 | if (result) | 659 | if (result) |
@@ -732,8 +668,7 @@ static int acpi_battery_read(int fid, struct seq_file *seq) | |||
732 | end: | 668 | end: |
733 | result = acpi_read_funcs[fid].print(seq, result); | 669 | result = acpi_read_funcs[fid].print(seq, result); |
734 | acpi_battery_check_result(battery, result); | 670 | acpi_battery_check_result(battery, result); |
735 | battery->flags.update[fid] = result; | 671 | battery->update[fid] = result; |
736 | mutex_unlock(&battery->mutex); | ||
737 | return result; | 672 | return result; |
738 | } | 673 | } |
739 | 674 | ||
@@ -900,20 +835,16 @@ static int acpi_battery_add(struct acpi_device *device) | |||
900 | if (!battery) | 835 | if (!battery) |
901 | return -ENOMEM; | 836 | return -ENOMEM; |
902 | 837 | ||
903 | mutex_init(&battery->mutex); | ||
904 | |||
905 | mutex_lock(&battery->mutex); | ||
906 | |||
907 | battery->device = device; | 838 | battery->device = device; |
908 | strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); | 839 | strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); |
909 | strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); | 840 | strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); |
910 | acpi_driver_data(device) = battery; | 841 | acpi_driver_data(device) = battery; |
911 | 842 | mutex_init(&battery->lock); | |
912 | result = acpi_battery_get_status(battery); | 843 | result = acpi_battery_get_status(battery); |
913 | if (result) | 844 | if (result) |
914 | goto end; | 845 | goto end; |
915 | 846 | ||
916 | battery->flags.init_update = 1; | 847 | battery->init_update = 1; |
917 | 848 | ||
918 | result = acpi_battery_add_fs(device); | 849 | result = acpi_battery_add_fs(device); |
919 | if (result) | 850 | if (result) |
@@ -939,8 +870,6 @@ static int acpi_battery_add(struct acpi_device *device) | |||
939 | kfree(battery); | 870 | kfree(battery); |
940 | } | 871 | } |
941 | 872 | ||
942 | mutex_unlock(&battery->mutex); | ||
943 | |||
944 | return result; | 873 | return result; |
945 | } | 874 | } |
946 | 875 | ||
@@ -954,22 +883,12 @@ static int acpi_battery_remove(struct acpi_device *device, int type) | |||
954 | 883 | ||
955 | battery = acpi_driver_data(device); | 884 | battery = acpi_driver_data(device); |
956 | 885 | ||
957 | mutex_lock(&battery->mutex); | ||
958 | |||
959 | status = acpi_remove_notify_handler(device->handle, | 886 | status = acpi_remove_notify_handler(device->handle, |
960 | ACPI_ALL_NOTIFY, | 887 | ACPI_ALL_NOTIFY, |
961 | acpi_battery_notify); | 888 | acpi_battery_notify); |
962 | 889 | ||
963 | acpi_battery_remove_fs(device); | 890 | acpi_battery_remove_fs(device); |
964 | 891 | mutex_destroy(&battery->lock); | |
965 | kfree(battery->bif_data.pointer); | ||
966 | |||
967 | kfree(battery->bst_data.pointer); | ||
968 | |||
969 | mutex_unlock(&battery->mutex); | ||
970 | |||
971 | mutex_destroy(&battery->mutex); | ||
972 | |||
973 | kfree(battery); | 892 | kfree(battery); |
974 | 893 | ||
975 | return 0; | 894 | return 0; |
@@ -985,7 +904,7 @@ static int acpi_battery_resume(struct acpi_device *device) | |||
985 | 904 | ||
986 | battery = device->driver_data; | 905 | battery = device->driver_data; |
987 | 906 | ||
988 | battery->flags.init_update = 1; | 907 | battery->init_update = 1; |
989 | 908 | ||
990 | return 0; | 909 | return 0; |
991 | } | 910 | } |