aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorVladimir Lebedev <vladimir.p.lebedev@intel.com>2007-03-19 10:45:50 -0400
committerLen Brown <len.brown@intel.com>2007-03-22 01:15:58 -0400
commit722062334b972c31a3b83dbf7e9b5a58bb2707dd (patch)
treea4d5aa458158435e5c4014316e26acbb5fe547cb /drivers/acpi
parent6845118b3b7a9cc2ba14dc665370217bc3ba8057 (diff)
ACPI: sbs: Common interface with CM battery
The SBS driver has tne features as CM battery: SBS update_time variable has tne same definition as CM battery 'update_time' variable. Signed-off-by: Vladimir Lebedev <vladimir.p.lebedev@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/sbs.c577
1 files changed, 319 insertions, 258 deletions
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 395664528dd1..c1bae106833c 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -31,6 +31,7 @@
31#include <asm/uaccess.h> 31#include <asm/uaccess.h>
32#include <linux/acpi.h> 32#include <linux/acpi.h>
33#include <linux/timer.h> 33#include <linux/timer.h>
34#include <linux/jiffies.h>
34#include <linux/delay.h> 35#include <linux/delay.h>
35 36
36#define ACPI_SBS_COMPONENT 0x00080000 37#define ACPI_SBS_COMPONENT 0x00080000
@@ -109,29 +110,19 @@ extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
109#define ACPI_SBS_WORD_DATA 1 110#define ACPI_SBS_WORD_DATA 1
110#define ACPI_SBS_BLOCK_DATA 2 111#define ACPI_SBS_BLOCK_DATA 2
111 112
112static struct semaphore sbs_sem; 113#define UPDATE_DELAY 10
113 114
114#define UPDATE_MODE QUEUE_UPDATE_MODE 115/* 0 - every time, > 0 - by update_time */
115/* REQUEST_UPDATE_MODE QUEUE_UPDATE_MODE */ 116static unsigned int update_time = 120;
116#define UPDATE_INFO_MODE 0
117#define UPDATE_TIME 60
118#define UPDATE_TIME2 0
119 117
120static int capacity_mode = CAPACITY_UNIT; 118static unsigned int capacity_mode = CAPACITY_UNIT;
121static int update_mode = UPDATE_MODE;
122static int update_info_mode = UPDATE_INFO_MODE;
123static int update_time = UPDATE_TIME;
124static int update_time2 = UPDATE_TIME2;
125 119
126module_param(capacity_mode, int, 0); 120module_param(update_time, uint, 0644);
127module_param(update_mode, int, 0); 121module_param(capacity_mode, uint, 0444);
128module_param(update_info_mode, int, 0);
129module_param(update_time, int, 0);
130module_param(update_time2, int, 0);
131 122
132static int acpi_sbs_add(struct acpi_device *device); 123static int acpi_sbs_add(struct acpi_device *device);
133static int acpi_sbs_remove(struct acpi_device *device, int type); 124static int acpi_sbs_remove(struct acpi_device *device, int type);
134static void acpi_sbs_update_queue(void *data); 125static int acpi_sbs_resume(struct acpi_device *device);
135 126
136static struct acpi_driver acpi_sbs_driver = { 127static struct acpi_driver acpi_sbs_driver = {
137 .name = "sbs", 128 .name = "sbs",
@@ -140,9 +131,14 @@ static struct acpi_driver acpi_sbs_driver = {
140 .ops = { 131 .ops = {
141 .add = acpi_sbs_add, 132 .add = acpi_sbs_add,
142 .remove = acpi_sbs_remove, 133 .remove = acpi_sbs_remove,
134 .resume = acpi_sbs_resume,
143 }, 135 },
144}; 136};
145 137
138struct acpi_ac {
139 int ac_present;
140};
141
146struct acpi_battery_info { 142struct acpi_battery_info {
147 int capacity_mode; 143 int capacity_mode;
148 s16 full_charge_capacity; 144 s16 full_charge_capacity;
@@ -160,9 +156,7 @@ struct acpi_battery_state {
160 s16 voltage; 156 s16 voltage;
161 s16 amperage; 157 s16 amperage;
162 s16 remaining_capacity; 158 s16 remaining_capacity;
163 s16 average_time_to_empty; 159 s16 battery_state;
164 s16 average_time_to_full;
165 s16 battery_status;
166}; 160};
167 161
168struct acpi_battery_alarm { 162struct acpi_battery_alarm {
@@ -171,9 +165,9 @@ struct acpi_battery_alarm {
171 165
172struct acpi_battery { 166struct acpi_battery {
173 int alive; 167 int alive;
174 int battery_present;
175 int id; 168 int id;
176 int init_state; 169 int init_state;
170 int battery_present;
177 struct acpi_sbs *sbs; 171 struct acpi_sbs *sbs;
178 struct acpi_battery_info info; 172 struct acpi_battery_info info;
179 struct acpi_battery_state state; 173 struct acpi_battery_state state;
@@ -185,18 +179,22 @@ struct acpi_sbs {
185 acpi_handle handle; 179 acpi_handle handle;
186 int base; 180 int base;
187 struct acpi_device *device; 181 struct acpi_device *device;
182 struct acpi_ec_smbus *smbus;
183 struct mutex mutex;
188 int sbsm_present; 184 int sbsm_present;
189 int sbsm_batteries_supported; 185 int sbsm_batteries_supported;
190 int ac_present;
191 struct proc_dir_entry *ac_entry; 186 struct proc_dir_entry *ac_entry;
187 struct acpi_ac ac;
192 struct acpi_battery battery[MAX_SBS_BAT]; 188 struct acpi_battery battery[MAX_SBS_BAT];
193 int update_info_mode;
194 int zombie; 189 int zombie;
195 int update_time;
196 int update_time2;
197 struct timer_list update_timer; 190 struct timer_list update_timer;
191 int run_cnt;
192 int update_proc_flg;
198}; 193};
199 194
195static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type);
196static void acpi_sbs_update_time(void *data);
197
200union sbs_rw_data { 198union sbs_rw_data {
201 u16 word; 199 u16 word;
202 u8 block[ACPI_SBS_BLOCK_MAX + 2]; 200 u8 block[ACPI_SBS_BLOCK_MAX + 2];
@@ -205,8 +203,6 @@ union sbs_rw_data {
205static int acpi_ec_sbs_access(struct acpi_sbs *sbs, u16 addr, 203static int acpi_ec_sbs_access(struct acpi_sbs *sbs, u16 addr,
206 char read_write, u8 command, int size, 204 char read_write, u8 command, int size,
207 union sbs_rw_data *data); 205 union sbs_rw_data *data);
208static void acpi_update_delay(struct acpi_sbs *sbs);
209static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type);
210 206
211/* -------------------------------------------------------------------------- 207/* --------------------------------------------------------------------------
212 SMBus Communication 208 SMBus Communication
@@ -383,11 +379,49 @@ acpi_sbs_write_word(struct acpi_sbs *sbs, int addr, int func, int word)
383 return result; 379 return result;
384} 380}
385 381
382static int sbs_zombie(struct acpi_sbs *sbs)
383{
384 return (sbs->zombie);
385}
386
387static int sbs_mutex_lock(struct acpi_sbs *sbs)
388{
389 if (sbs_zombie(sbs)) {
390 return -ENODEV;
391 }
392 mutex_lock(&sbs->mutex);
393 return 0;
394}
395
396static void sbs_mutex_unlock(struct acpi_sbs *sbs)
397{
398 mutex_unlock(&sbs->mutex);
399}
400
386/* -------------------------------------------------------------------------- 401/* --------------------------------------------------------------------------
387 Smart Battery System Management 402 Smart Battery System Management
388 -------------------------------------------------------------------------- */ 403 -------------------------------------------------------------------------- */
389 404
390/* Smart Battery */ 405static int acpi_check_update_proc(struct acpi_sbs *sbs)
406{
407 acpi_status status = AE_OK;
408
409 if (update_time == 0) {
410 sbs->update_proc_flg = 0;
411 return 0;
412 }
413 if (sbs->update_proc_flg == 0) {
414 status = acpi_os_execute(OSL_GPE_HANDLER,
415 acpi_sbs_update_time, sbs);
416 if (status != AE_OK) {
417 ACPI_EXCEPTION((AE_INFO, status,
418 "acpi_os_execute() failed"));
419 return 1;
420 }
421 sbs->update_proc_flg = 1;
422 }
423 return 0;
424}
391 425
392static int acpi_sbs_generate_event(struct acpi_device *device, 426static int acpi_sbs_generate_event(struct acpi_device *device,
393 int event, int state, char *bid, char *class) 427 int event, int state, char *bid, char *class)
@@ -430,16 +464,6 @@ static int acpi_battery_get_present(struct acpi_battery *battery)
430 return result; 464 return result;
431} 465}
432 466
433static int acpi_battery_is_present(struct acpi_battery *battery)
434{
435 return (battery->battery_present);
436}
437
438static int acpi_ac_is_present(struct acpi_sbs *sbs)
439{
440 return (sbs->ac_present);
441}
442
443static int acpi_battery_select(struct acpi_battery *battery) 467static int acpi_battery_select(struct acpi_battery *battery)
444{ 468{
445 struct acpi_sbs *sbs = battery->sbs; 469 struct acpi_sbs *sbs = battery->sbs;
@@ -447,7 +471,7 @@ static int acpi_battery_select(struct acpi_battery *battery)
447 s16 state; 471 s16 state;
448 int foo; 472 int foo;
449 473
450 if (battery->sbs->sbsm_present) { 474 if (sbs->sbsm_present) {
451 475
452 /* Take special care not to knobble other nibbles of 476 /* Take special care not to knobble other nibbles of
453 * state (aka selector_state), since 477 * state (aka selector_state), since
@@ -523,6 +547,8 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
523 &battery->info.design_capacity); 547 &battery->info.design_capacity);
524 548
525 if (result) { 549 if (result) {
550 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
551 "acpi_sbs_read_word() failed"));
526 goto end; 552 goto end;
527 } 553 }
528 554
@@ -573,6 +599,8 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
573 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1c, 599 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1c,
574 &battery->info.serial_number); 600 &battery->info.serial_number);
575 if (result) { 601 if (result) {
602 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
603 "acpi_sbs_read_word() failed"));
576 goto end; 604 goto end;
577 } 605 }
578 606
@@ -604,22 +632,11 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
604 return result; 632 return result;
605} 633}
606 634
607static void acpi_update_delay(struct acpi_sbs *sbs)
608{
609 if (sbs->zombie) {
610 return;
611 }
612 if (sbs->update_time2 > 0) {
613 msleep(sbs->update_time2 * 1000);
614 }
615}
616
617static int acpi_battery_get_state(struct acpi_battery *battery) 635static int acpi_battery_get_state(struct acpi_battery *battery)
618{ 636{
619 struct acpi_sbs *sbs = battery->sbs; 637 struct acpi_sbs *sbs = battery->sbs;
620 int result = 0; 638 int result = 0;
621 639
622 acpi_update_delay(battery->sbs);
623 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x09, 640 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x09,
624 &battery->state.voltage); 641 &battery->state.voltage);
625 if (result) { 642 if (result) {
@@ -628,7 +645,6 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
628 goto end; 645 goto end;
629 } 646 }
630 647
631 acpi_update_delay(battery->sbs);
632 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0a, 648 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0a,
633 &battery->state.amperage); 649 &battery->state.amperage);
634 if (result) { 650 if (result) {
@@ -637,7 +653,6 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
637 goto end; 653 goto end;
638 } 654 }
639 655
640 acpi_update_delay(battery->sbs);
641 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0f, 656 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0f,
642 &battery->state.remaining_capacity); 657 &battery->state.remaining_capacity);
643 if (result) { 658 if (result) {
@@ -646,35 +661,14 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
646 goto end; 661 goto end;
647 } 662 }
648 663
649 acpi_update_delay(battery->sbs);
650 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x12,
651 &battery->state.average_time_to_empty);
652 if (result) {
653 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
654 "acpi_sbs_read_word() failed"));
655 goto end;
656 }
657
658 acpi_update_delay(battery->sbs);
659 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x13,
660 &battery->state.average_time_to_full);
661 if (result) {
662 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
663 "acpi_sbs_read_word() failed"));
664 goto end;
665 }
666
667 acpi_update_delay(battery->sbs);
668 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x16, 664 result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x16,
669 &battery->state.battery_status); 665 &battery->state.battery_state);
670 if (result) { 666 if (result) {
671 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 667 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
672 "acpi_sbs_read_word() failed")); 668 "acpi_sbs_read_word() failed"));
673 goto end; 669 goto end;
674 } 670 }
675 671
676 acpi_update_delay(battery->sbs);
677
678 end: 672 end:
679 return result; 673 return result;
680} 674}
@@ -692,8 +686,6 @@ static int acpi_battery_get_alarm(struct acpi_battery *battery)
692 goto end; 686 goto end;
693 } 687 }
694 688
695 acpi_update_delay(battery->sbs);
696
697 end: 689 end:
698 690
699 return result; 691 return result;
@@ -751,6 +743,7 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
751 743
752static int acpi_battery_set_mode(struct acpi_battery *battery) 744static int acpi_battery_set_mode(struct acpi_battery *battery)
753{ 745{
746 struct acpi_sbs *sbs = battery->sbs;
754 int result = 0; 747 int result = 0;
755 s16 battery_mode; 748 s16 battery_mode;
756 749
@@ -758,7 +751,7 @@ static int acpi_battery_set_mode(struct acpi_battery *battery)
758 goto end; 751 goto end;
759 } 752 }
760 753
761 result = acpi_sbs_read_word(battery->sbs, 754 result = acpi_sbs_read_word(sbs,
762 ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode); 755 ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode);
763 if (result) { 756 if (result) {
764 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 757 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -771,7 +764,7 @@ static int acpi_battery_set_mode(struct acpi_battery *battery)
771 } else { 764 } else {
772 battery_mode |= 0x8000; 765 battery_mode |= 0x8000;
773 } 766 }
774 result = acpi_sbs_write_word(battery->sbs, 767 result = acpi_sbs_write_word(sbs,
775 ACPI_SB_SMBUS_ADDR, 0x03, battery_mode); 768 ACPI_SB_SMBUS_ADDR, 0x03, battery_mode);
776 if (result) { 769 if (result) {
777 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 770 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -779,7 +772,7 @@ static int acpi_battery_set_mode(struct acpi_battery *battery)
779 goto end; 772 goto end;
780 } 773 }
781 774
782 result = acpi_sbs_read_word(battery->sbs, 775 result = acpi_sbs_read_word(sbs,
783 ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode); 776 ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode);
784 if (result) { 777 if (result) {
785 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 778 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -798,7 +791,7 @@ static int acpi_battery_init(struct acpi_battery *battery)
798 result = acpi_battery_select(battery); 791 result = acpi_battery_select(battery);
799 if (result) { 792 if (result) {
800 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 793 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
801 "acpi_battery_init() failed")); 794 "acpi_battery_select() failed"));
802 goto end; 795 goto end;
803 } 796 }
804 797
@@ -848,7 +841,7 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)
848 goto end; 841 goto end;
849 } 842 }
850 843
851 sbs->ac_present = (charger_status & 0x8000) >> 15; 844 sbs->ac.ac_present = (charger_status & 0x8000) >> 15;
852 845
853 end: 846 end:
854 847
@@ -945,24 +938,27 @@ static struct proc_dir_entry *acpi_battery_dir = NULL;
945static int acpi_battery_read_info(struct seq_file *seq, void *offset) 938static int acpi_battery_read_info(struct seq_file *seq, void *offset)
946{ 939{
947 struct acpi_battery *battery = seq->private; 940 struct acpi_battery *battery = seq->private;
941 struct acpi_sbs *sbs = battery->sbs;
948 int cscale; 942 int cscale;
949 int result = 0; 943 int result = 0;
950 944
951 if (battery->sbs->zombie) { 945 if (sbs_mutex_lock(sbs)) {
952 return -ENODEV; 946 return -ENODEV;
953 } 947 }
954 948
955 down(&sbs_sem); 949 result = acpi_check_update_proc(sbs);
950 if (result)
951 goto end;
956 952
957 if (update_mode == REQUEST_UPDATE_MODE) { 953 if (update_time == 0) {
958 result = acpi_sbs_update_run(battery->sbs, DATA_TYPE_INFO); 954 result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_INFO);
959 if (result) { 955 if (result) {
960 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 956 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
961 "acpi_sbs_update_run() failed")); 957 "acpi_sbs_update_run() failed"));
962 } 958 }
963 } 959 }
964 960
965 if (acpi_battery_is_present(battery)) { 961 if (battery->battery_present) {
966 seq_printf(seq, "present: yes\n"); 962 seq_printf(seq, "present: yes\n");
967 } else { 963 } else {
968 seq_printf(seq, "present: no\n"); 964 seq_printf(seq, "present: no\n");
@@ -974,13 +970,13 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
974 } else { 970 } else {
975 cscale = battery->info.ipscale; 971 cscale = battery->info.ipscale;
976 } 972 }
977 seq_printf(seq, "design capacity: %i%s", 973 seq_printf(seq, "design capacity: %i%s\n",
978 battery->info.design_capacity * cscale, 974 battery->info.design_capacity * cscale,
979 battery->info.capacity_mode ? "0 mWh\n" : " mAh\n"); 975 battery->info.capacity_mode ? "0 mWh" : " mAh");
980 976
981 seq_printf(seq, "last full capacity: %i%s", 977 seq_printf(seq, "last full capacity: %i%s\n",
982 battery->info.full_charge_capacity * cscale, 978 battery->info.full_charge_capacity * cscale,
983 battery->info.capacity_mode ? "0 mWh\n" : " mAh\n"); 979 battery->info.capacity_mode ? "0 mWh" : " mAh");
984 980
985 seq_printf(seq, "battery technology: rechargeable\n"); 981 seq_printf(seq, "battery technology: rechargeable\n");
986 982
@@ -1006,7 +1002,7 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
1006 1002
1007 end: 1003 end:
1008 1004
1009 up(&sbs_sem); 1005 sbs_mutex_unlock(sbs);
1010 1006
1011 return result; 1007 return result;
1012} 1008}
@@ -1018,26 +1014,29 @@ static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
1018 1014
1019static int acpi_battery_read_state(struct seq_file *seq, void *offset) 1015static int acpi_battery_read_state(struct seq_file *seq, void *offset)
1020{ 1016{
1021 struct acpi_battery *battery = (struct acpi_battery *)seq->private; 1017 struct acpi_battery *battery = seq->private;
1018 struct acpi_sbs *sbs = battery->sbs;
1022 int result = 0; 1019 int result = 0;
1023 int cscale; 1020 int cscale;
1024 int foo; 1021 int foo;
1025 1022
1026 if (battery->sbs->zombie) { 1023 if (sbs_mutex_lock(sbs)) {
1027 return -ENODEV; 1024 return -ENODEV;
1028 } 1025 }
1029 1026
1030 down(&sbs_sem); 1027 result = acpi_check_update_proc(sbs);
1028 if (result)
1029 goto end;
1031 1030
1032 if (update_mode == REQUEST_UPDATE_MODE) { 1031 if (update_time == 0) {
1033 result = acpi_sbs_update_run(battery->sbs, DATA_TYPE_STATE); 1032 result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_STATE);
1034 if (result) { 1033 if (result) {
1035 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 1034 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1036 "acpi_sbs_update_run() failed")); 1035 "acpi_sbs_update_run() failed"));
1037 } 1036 }
1038 } 1037 }
1039 1038
1040 if (acpi_battery_is_present(battery)) { 1039 if (battery->battery_present) {
1041 seq_printf(seq, "present: yes\n"); 1040 seq_printf(seq, "present: yes\n");
1042 } else { 1041 } else {
1043 seq_printf(seq, "present: no\n"); 1042 seq_printf(seq, "present: no\n");
@@ -1050,7 +1049,7 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
1050 cscale = battery->info.ipscale; 1049 cscale = battery->info.ipscale;
1051 } 1050 }
1052 1051
1053 if (battery->state.battery_status & 0x0010) { 1052 if (battery->state.battery_state & 0x0010) {
1054 seq_printf(seq, "capacity state: critical\n"); 1053 seq_printf(seq, "capacity state: critical\n");
1055 } else { 1054 } else {
1056 seq_printf(seq, "capacity state: ok\n"); 1055 seq_printf(seq, "capacity state: ok\n");
@@ -1074,16 +1073,16 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
1074 battery->info.capacity_mode ? "mW" : "mA"); 1073 battery->info.capacity_mode ? "mW" : "mA");
1075 } 1074 }
1076 1075
1077 seq_printf(seq, "remaining capacity: %i%s", 1076 seq_printf(seq, "remaining capacity: %i%s\n",
1078 battery->state.remaining_capacity * cscale, 1077 battery->state.remaining_capacity * cscale,
1079 battery->info.capacity_mode ? "0 mWh\n" : " mAh\n"); 1078 battery->info.capacity_mode ? "0 mWh" : " mAh");
1080 1079
1081 seq_printf(seq, "present voltage: %i mV\n", 1080 seq_printf(seq, "present voltage: %i mV\n",
1082 battery->state.voltage * battery->info.vscale); 1081 battery->state.voltage * battery->info.vscale);
1083 1082
1084 end: 1083 end:
1085 1084
1086 up(&sbs_sem); 1085 sbs_mutex_unlock(sbs);
1087 1086
1088 return result; 1087 return result;
1089} 1088}
@@ -1096,24 +1095,27 @@ static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
1096static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) 1095static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
1097{ 1096{
1098 struct acpi_battery *battery = seq->private; 1097 struct acpi_battery *battery = seq->private;
1098 struct acpi_sbs *sbs = battery->sbs;
1099 int result = 0; 1099 int result = 0;
1100 int cscale; 1100 int cscale;
1101 1101
1102 if (battery->sbs->zombie) { 1102 if (sbs_mutex_lock(sbs)) {
1103 return -ENODEV; 1103 return -ENODEV;
1104 } 1104 }
1105 1105
1106 down(&sbs_sem); 1106 result = acpi_check_update_proc(sbs);
1107 if (result)
1108 goto end;
1107 1109
1108 if (update_mode == REQUEST_UPDATE_MODE) { 1110 if (update_time == 0) {
1109 result = acpi_sbs_update_run(battery->sbs, DATA_TYPE_ALARM); 1111 result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_ALARM);
1110 if (result) { 1112 if (result) {
1111 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 1113 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1112 "acpi_sbs_update_run() failed")); 1114 "acpi_sbs_update_run() failed"));
1113 } 1115 }
1114 } 1116 }
1115 1117
1116 if (!acpi_battery_is_present(battery)) { 1118 if (!battery->battery_present) {
1117 seq_printf(seq, "present: no\n"); 1119 seq_printf(seq, "present: no\n");
1118 goto end; 1120 goto end;
1119 } 1121 }
@@ -1126,16 +1128,16 @@ static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
1126 1128
1127 seq_printf(seq, "alarm: "); 1129 seq_printf(seq, "alarm: ");
1128 if (battery->alarm.remaining_capacity) { 1130 if (battery->alarm.remaining_capacity) {
1129 seq_printf(seq, "%i%s", 1131 seq_printf(seq, "%i%s\n",
1130 battery->alarm.remaining_capacity * cscale, 1132 battery->alarm.remaining_capacity * cscale,
1131 battery->info.capacity_mode ? "0 mWh\n" : " mAh\n"); 1133 battery->info.capacity_mode ? "0 mWh" : " mAh");
1132 } else { 1134 } else {
1133 seq_printf(seq, "disabled\n"); 1135 seq_printf(seq, "disabled\n");
1134 } 1136 }
1135 1137
1136 end: 1138 end:
1137 1139
1138 up(&sbs_sem); 1140 sbs_mutex_unlock(sbs);
1139 1141
1140 return result; 1142 return result;
1141} 1143}
@@ -1146,16 +1148,19 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer,
1146{ 1148{
1147 struct seq_file *seq = file->private_data; 1149 struct seq_file *seq = file->private_data;
1148 struct acpi_battery *battery = seq->private; 1150 struct acpi_battery *battery = seq->private;
1151 struct acpi_sbs *sbs = battery->sbs;
1149 char alarm_string[12] = { '\0' }; 1152 char alarm_string[12] = { '\0' };
1150 int result, old_alarm, new_alarm; 1153 int result, old_alarm, new_alarm;
1151 1154
1152 if (battery->sbs->zombie) { 1155 if (sbs_mutex_lock(sbs)) {
1153 return -ENODEV; 1156 return -ENODEV;
1154 } 1157 }
1155 1158
1156 down(&sbs_sem); 1159 result = acpi_check_update_proc(sbs);
1160 if (result)
1161 goto end;
1157 1162
1158 if (!acpi_battery_is_present(battery)) { 1163 if (!battery->battery_present) {
1159 result = -ENODEV; 1164 result = -ENODEV;
1160 goto end; 1165 goto end;
1161 } 1166 }
@@ -1191,7 +1196,7 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer,
1191 } 1196 }
1192 1197
1193 end: 1198 end:
1194 up(&sbs_sem); 1199 sbs_mutex_unlock(sbs);
1195 1200
1196 if (result) { 1201 if (result) {
1197 return result; 1202 return result;
@@ -1239,14 +1244,12 @@ static int acpi_ac_read_state(struct seq_file *seq, void *offset)
1239 struct acpi_sbs *sbs = seq->private; 1244 struct acpi_sbs *sbs = seq->private;
1240 int result; 1245 int result;
1241 1246
1242 if (sbs->zombie) { 1247 if (sbs_mutex_lock(sbs)) {
1243 return -ENODEV; 1248 return -ENODEV;
1244 } 1249 }
1245 1250
1246 down(&sbs_sem); 1251 if (update_time == 0) {
1247 1252 result = acpi_sbs_update_run(sbs, -1, DATA_TYPE_AC_STATE);
1248 if (update_mode == REQUEST_UPDATE_MODE) {
1249 result = acpi_sbs_update_run(sbs, DATA_TYPE_AC_STATE);
1250 if (result) { 1253 if (result) {
1251 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 1254 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1252 "acpi_sbs_update_run() failed")); 1255 "acpi_sbs_update_run() failed"));
@@ -1254,9 +1257,9 @@ static int acpi_ac_read_state(struct seq_file *seq, void *offset)
1254 } 1257 }
1255 1258
1256 seq_printf(seq, "state: %s\n", 1259 seq_printf(seq, "state: %s\n",
1257 sbs->ac_present ? "on-line" : "off-line"); 1260 sbs->ac.ac_present ? "on-line" : "off-line");
1258 1261
1259 up(&sbs_sem); 1262 sbs_mutex_unlock(sbs);
1260 1263
1261 return 0; 1264 return 0;
1262} 1265}
@@ -1309,7 +1312,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
1309 goto end; 1312 goto end;
1310 } 1313 }
1311 1314
1312 is_present = acpi_battery_is_present(battery); 1315 is_present = battery->battery_present;
1313 1316
1314 if (is_present) { 1317 if (is_present) {
1315 result = acpi_battery_init(battery); 1318 result = acpi_battery_init(battery);
@@ -1336,6 +1339,10 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
1336 } 1339 }
1337 battery->alive = 1; 1340 battery->alive = 1;
1338 1341
1342 printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",
1343 ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), dir_name,
1344 sbs->battery->battery_present ? "present" : "absent");
1345
1339 end: 1346 end:
1340 return result; 1347 return result;
1341} 1348}
@@ -1370,6 +1377,10 @@ static int acpi_ac_add(struct acpi_sbs *sbs)
1370 goto end; 1377 goto end;
1371 } 1378 }
1372 1379
1380 printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",
1381 ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
1382 ACPI_AC_DIR_NAME, sbs->ac.ac_present ? "on-line" : "off-line");
1383
1373 end: 1384 end:
1374 1385
1375 return result; 1386 return result;
@@ -1383,29 +1394,48 @@ static void acpi_ac_remove(struct acpi_sbs *sbs)
1383 } 1394 }
1384} 1395}
1385 1396
1386static void acpi_sbs_update_queue_run(unsigned long data) 1397static void acpi_sbs_update_time_run(unsigned long data)
1387{ 1398{
1388 acpi_os_execute(OSL_GPE_HANDLER, acpi_sbs_update_queue, (void *)data); 1399 acpi_os_execute(OSL_GPE_HANDLER, acpi_sbs_update_time, (void *)data);
1389} 1400}
1390 1401
1391static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type) 1402static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)
1392{ 1403{
1393 struct acpi_battery *battery; 1404 struct acpi_battery *battery;
1394 int result = 0; 1405 int result = 0, cnt;
1395 int old_ac_present; 1406 int old_ac_present = -1;
1396 int old_battery_present; 1407 int old_battery_present = -1;
1397 int new_ac_present; 1408 int new_ac_present = -1;
1398 int new_battery_present; 1409 int new_battery_present = -1;
1399 int id; 1410 int id_min = 0, id_max = MAX_SBS_BAT - 1;
1400 char dir_name[32]; 1411 char dir_name[32];
1401 int do_battery_init, do_ac_init; 1412 int do_battery_init = 0, do_ac_init = 0;
1402 s16 old_remaining_capacity; 1413 int old_remaining_capacity = 0;
1414 int update_ac = 1, update_battery = 1;
1415 int up_tm = update_time;
1416
1417 if (sbs_zombie(sbs)) {
1418 goto end;
1419 }
1403 1420
1404 if (sbs->zombie) { 1421 if (id >= 0) {
1422 id_min = id_max = id;
1423 }
1424
1425 if (data_type == DATA_TYPE_COMMON && up_tm > 0) {
1426 cnt = up_tm / (up_tm > UPDATE_DELAY ? UPDATE_DELAY : up_tm);
1427 if (sbs->run_cnt % cnt != 0) {
1428 update_battery = 0;
1429 }
1430 }
1431
1432 sbs->run_cnt++;
1433
1434 if (!update_ac && !update_battery) {
1405 goto end; 1435 goto end;
1406 } 1436 }
1407 1437
1408 old_ac_present = acpi_ac_is_present(sbs); 1438 old_ac_present = sbs->ac.ac_present;
1409 1439
1410 result = acpi_ac_get_present(sbs); 1440 result = acpi_ac_get_present(sbs);
1411 if (result) { 1441 if (result) {
@@ -1413,15 +1443,36 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
1413 "acpi_ac_get_present() failed")); 1443 "acpi_ac_get_present() failed"));
1414 } 1444 }
1415 1445
1416 new_ac_present = acpi_ac_is_present(sbs); 1446 new_ac_present = sbs->ac.ac_present;
1417 1447
1418 do_ac_init = (old_ac_present != new_ac_present); 1448 do_ac_init = (old_ac_present != new_ac_present);
1449 if (sbs->run_cnt == 1 && data_type == DATA_TYPE_COMMON) {
1450 do_ac_init = 1;
1451 }
1419 1452
1420 if (data_type == DATA_TYPE_AC_STATE) { 1453 if (do_ac_init) {
1454 result = acpi_sbs_generate_event(sbs->device,
1455 ACPI_SBS_AC_NOTIFY_STATUS,
1456 new_ac_present,
1457 ACPI_AC_DIR_NAME,
1458 ACPI_AC_CLASS);
1459 if (result) {
1460 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1461 "acpi_sbs_generate_event() failed"));
1462 }
1463 }
1464
1465 if (data_type == DATA_TYPE_COMMON) {
1466 if (!do_ac_init && !update_battery) {
1467 goto end;
1468 }
1469 }
1470
1471 if (data_type == DATA_TYPE_AC_STATE && !do_ac_init) {
1421 goto end; 1472 goto end;
1422 } 1473 }
1423 1474
1424 for (id = 0; id < MAX_SBS_BAT; id++) { 1475 for (id = id_min; id <= id_max; id++) {
1425 battery = &sbs->battery[id]; 1476 battery = &sbs->battery[id];
1426 if (battery->alive == 0) { 1477 if (battery->alive == 0) {
1427 continue; 1478 continue;
@@ -1429,41 +1480,27 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
1429 1480
1430 old_remaining_capacity = battery->state.remaining_capacity; 1481 old_remaining_capacity = battery->state.remaining_capacity;
1431 1482
1432 old_battery_present = acpi_battery_is_present(battery); 1483 old_battery_present = battery->battery_present;
1433 1484
1434 result = acpi_battery_select(battery); 1485 result = acpi_battery_select(battery);
1435 if (result) { 1486 if (result) {
1436 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 1487 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1437 "acpi_battery_select() failed")); 1488 "acpi_battery_select() failed"));
1438 } 1489 }
1439 if (sbs->zombie) {
1440 goto end;
1441 }
1442 1490
1443 result = acpi_battery_get_present(battery); 1491 result = acpi_battery_get_present(battery);
1444 if (result) { 1492 if (result) {
1445 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 1493 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1446 "acpi_battery_get_present() failed")); 1494 "acpi_battery_get_present() failed"));
1447 } 1495 }
1448 if (sbs->zombie) {
1449 goto end;
1450 }
1451 1496
1452 new_battery_present = acpi_battery_is_present(battery); 1497 new_battery_present = battery->battery_present;
1453 1498
1454 do_battery_init = ((old_battery_present != new_battery_present) 1499 do_battery_init = ((old_battery_present != new_battery_present)
1455 && new_battery_present); 1500 && new_battery_present);
1456 1501 if (!new_battery_present)
1457 if (sbs->zombie) { 1502 goto event;
1458 goto end; 1503 if (do_ac_init || do_battery_init) {
1459 }
1460 if (do_ac_init || do_battery_init ||
1461 update_info_mode || sbs->update_info_mode) {
1462 if (sbs->update_info_mode) {
1463 sbs->update_info_mode = 0;
1464 } else {
1465 sbs->update_info_mode = 1;
1466 }
1467 result = acpi_battery_init(battery); 1504 result = acpi_battery_init(battery);
1468 if (result) { 1505 if (result) {
1469 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 1506 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -1471,52 +1508,64 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
1471 "failed")); 1508 "failed"));
1472 } 1509 }
1473 } 1510 }
1474 if (data_type == DATA_TYPE_INFO) { 1511 if (sbs_zombie(sbs)) {
1475 continue;
1476 }
1477
1478 if (sbs->zombie) {
1479 goto end; 1512 goto end;
1480 } 1513 }
1481 if (new_battery_present) { 1514
1482 result = acpi_battery_get_alarm(battery); 1515 if ((data_type == DATA_TYPE_COMMON
1516 || data_type == DATA_TYPE_INFO)
1517 && new_battery_present) {
1518 result = acpi_battery_get_info(battery);
1483 if (result) { 1519 if (result) {
1484 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 1520 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1485 "acpi_battery_get_alarm() " 1521 "acpi_battery_get_info() failed"));
1486 "failed"));
1487 }
1488 if (data_type == DATA_TYPE_ALARM) {
1489 continue;
1490 } 1522 }
1523 }
1524 if (data_type == DATA_TYPE_INFO) {
1525 continue;
1526 }
1527 if (sbs_zombie(sbs)) {
1528 goto end;
1529 }
1491 1530
1531 if ((data_type == DATA_TYPE_COMMON
1532 || data_type == DATA_TYPE_STATE)
1533 && new_battery_present) {
1492 result = acpi_battery_get_state(battery); 1534 result = acpi_battery_get_state(battery);
1493 if (result) { 1535 if (result) {
1494 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 1536 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1495 "acpi_battery_get_state() " 1537 "acpi_battery_get_state() failed"));
1496 "failed"));
1497 } 1538 }
1498 } 1539 }
1499 if (sbs->zombie) { 1540 if (data_type == DATA_TYPE_STATE) {
1500 goto end; 1541 goto event;
1501 } 1542 }
1502 if (data_type != DATA_TYPE_COMMON) { 1543 if (sbs_zombie(sbs)) {
1503 continue; 1544 goto end;
1504 } 1545 }
1505 1546
1506 if (old_battery_present != new_battery_present) { 1547 if ((data_type == DATA_TYPE_COMMON
1507 sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id); 1548 || data_type == DATA_TYPE_ALARM)
1508 result = acpi_sbs_generate_event(sbs->device, 1549 && new_battery_present) {
1509 ACPI_SBS_BATTERY_NOTIFY_STATUS, 1550 result = acpi_battery_get_alarm(battery);
1510 new_battery_present,
1511 dir_name,
1512 ACPI_BATTERY_CLASS);
1513 if (result) { 1551 if (result) {
1514 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 1552 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1515 "acpi_sbs_generate_event() " 1553 "acpi_battery_get_alarm() "
1516 "failed")); 1554 "failed"));
1517 } 1555 }
1518 } 1556 }
1519 if (old_remaining_capacity != battery->state.remaining_capacity) { 1557 if (data_type == DATA_TYPE_ALARM) {
1558 continue;
1559 }
1560 if (sbs_zombie(sbs)) {
1561 goto end;
1562 }
1563
1564 event:
1565
1566 if (old_battery_present != new_battery_present || do_ac_init ||
1567 old_remaining_capacity !=
1568 battery->state.remaining_capacity) {
1520 sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id); 1569 sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
1521 result = acpi_sbs_generate_event(sbs->device, 1570 result = acpi_sbs_generate_event(sbs->device,
1522 ACPI_SBS_BATTERY_NOTIFY_STATUS, 1571 ACPI_SBS_BATTERY_NOTIFY_STATUS,
@@ -1525,71 +1574,62 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
1525 ACPI_BATTERY_CLASS); 1574 ACPI_BATTERY_CLASS);
1526 if (result) { 1575 if (result) {
1527 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 1576 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1528 "acpi_sbs_generate_event() failed")); 1577 "acpi_sbs_generate_event() "
1578 "failed"));
1529 } 1579 }
1530 } 1580 }
1531
1532 }
1533 if (sbs->zombie) {
1534 goto end;
1535 }
1536 if (data_type != DATA_TYPE_COMMON) {
1537 goto end;
1538 }
1539
1540 if (old_ac_present != new_ac_present) {
1541 result = acpi_sbs_generate_event(sbs->device,
1542 ACPI_SBS_AC_NOTIFY_STATUS,
1543 new_ac_present,
1544 ACPI_AC_DIR_NAME,
1545 ACPI_AC_CLASS);
1546 if (result) {
1547 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1548 "acpi_sbs_generate_event() failed"));
1549 }
1550 } 1581 }
1551 1582
1552 end: 1583 end:
1584
1553 return result; 1585 return result;
1554} 1586}
1555 1587
1556static void acpi_sbs_update_queue(void *data) 1588static void acpi_sbs_update_time(void *data)
1557{ 1589{
1558 struct acpi_sbs *sbs = data; 1590 struct acpi_sbs *sbs = data;
1559 unsigned long delay = -1; 1591 unsigned long delay = -1;
1560 int result; 1592 int result;
1593 unsigned int up_tm = update_time;
1561 1594
1562 if (sbs->zombie) { 1595 if (sbs_mutex_lock(sbs))
1563 goto end; 1596 return;
1564 }
1565 1597
1566 result = acpi_sbs_update_run(sbs, DATA_TYPE_COMMON); 1598 result = acpi_sbs_update_run(sbs, -1, DATA_TYPE_COMMON);
1567 if (result) { 1599 if (result) {
1568 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 1600 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1569 "acpi_sbs_update_run() failed")); 1601 "acpi_sbs_update_run() failed"));
1570 } 1602 }
1571 1603
1572 if (sbs->zombie) { 1604 if (sbs_zombie(sbs)) {
1573 goto end; 1605 goto end;
1574 } 1606 }
1575 1607
1576 if (update_mode == REQUEST_UPDATE_MODE) { 1608 if (!up_tm) {
1577 goto end; 1609 if (timer_pending(&sbs->update_timer))
1610 del_timer(&sbs->update_timer);
1611 } else {
1612 delay = (up_tm > UPDATE_DELAY ? UPDATE_DELAY : up_tm);
1613 delay = jiffies + HZ * delay;
1614 if (timer_pending(&sbs->update_timer)) {
1615 mod_timer(&sbs->update_timer, delay);
1616 } else {
1617 sbs->update_timer.data = (unsigned long)data;
1618 sbs->update_timer.function = acpi_sbs_update_time_run;
1619 sbs->update_timer.expires = delay;
1620 add_timer(&sbs->update_timer);
1621 }
1578 } 1622 }
1579 1623
1580 delay = jiffies + HZ * update_time;
1581 sbs->update_timer.data = (unsigned long)data;
1582 sbs->update_timer.function = acpi_sbs_update_queue_run;
1583 sbs->update_timer.expires = delay;
1584 add_timer(&sbs->update_timer);
1585 end: 1624 end:
1586 ; 1625
1626 sbs_mutex_unlock(sbs);
1587} 1627}
1588 1628
1589static int acpi_sbs_add(struct acpi_device *device) 1629static int acpi_sbs_add(struct acpi_device *device)
1590{ 1630{
1591 struct acpi_sbs *sbs = NULL; 1631 struct acpi_sbs *sbs = NULL;
1592 int result; 1632 int result = 0, remove_result = 0;
1593 unsigned long sbs_obj; 1633 unsigned long sbs_obj;
1594 int id; 1634 int id;
1595 acpi_status status = AE_OK; 1635 acpi_status status = AE_OK;
@@ -1604,33 +1644,34 @@ static int acpi_sbs_add(struct acpi_device *device)
1604 1644
1605 sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL); 1645 sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL);
1606 if (!sbs) { 1646 if (!sbs) {
1607 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "kmalloc() failed")); 1647 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "kzalloc() failed"));
1608 return -ENOMEM; 1648 result = -ENOMEM;
1649 goto end;
1609 } 1650 }
1610 sbs->base = (val & 0xff00ull) >> 8;
1611 1651
1652 mutex_init(&sbs->mutex);
1653
1654 sbs_mutex_lock(sbs);
1655
1656 sbs->base = (val & 0xff00ull) >> 8;
1612 sbs->device = device; 1657 sbs->device = device;
1613 1658
1614 strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME); 1659 strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME);
1615 strcpy(acpi_device_class(device), ACPI_SBS_CLASS); 1660 strcpy(acpi_device_class(device), ACPI_SBS_CLASS);
1616 acpi_driver_data(device) = sbs; 1661 acpi_driver_data(device) = sbs;
1617 1662
1618 sbs->update_time = 0;
1619 sbs->update_time2 = 0;
1620
1621 result = acpi_ac_add(sbs); 1663 result = acpi_ac_add(sbs);
1622 if (result) { 1664 if (result) {
1623 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed")); 1665 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed"));
1624 goto end; 1666 goto end;
1625 } 1667 }
1626 result = acpi_evaluate_integer(device->handle, "_SBS", NULL, &sbs_obj); 1668 status = acpi_evaluate_integer(device->handle, "_SBS", NULL, &sbs_obj);
1627 if (ACPI_FAILURE(result)) { 1669 if (status) {
1628 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 1670 ACPI_EXCEPTION((AE_INFO, status,
1629 "acpi_evaluate_integer() failed")); 1671 "acpi_evaluate_integer() failed"));
1630 result = -EIO; 1672 result = -EIO;
1631 goto end; 1673 goto end;
1632 } 1674 }
1633
1634 if (sbs_obj > 0) { 1675 if (sbs_obj > 0) {
1635 result = acpi_sbsm_get_info(sbs); 1676 result = acpi_sbsm_get_info(sbs);
1636 if (result) { 1677 if (result) {
@@ -1640,6 +1681,7 @@ static int acpi_sbs_add(struct acpi_device *device)
1640 } 1681 }
1641 sbs->sbsm_present = 1; 1682 sbs->sbsm_present = 1;
1642 } 1683 }
1684
1643 if (sbs->sbsm_present == 0) { 1685 if (sbs->sbsm_present == 0) {
1644 result = acpi_battery_add(sbs, 0); 1686 result = acpi_battery_add(sbs, 0);
1645 if (result) { 1687 if (result) {
@@ -1653,8 +1695,7 @@ static int acpi_sbs_add(struct acpi_device *device)
1653 result = acpi_battery_add(sbs, id); 1695 result = acpi_battery_add(sbs, id);
1654 if (result) { 1696 if (result) {
1655 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 1697 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1656 "acpi_battery_add() " 1698 "acpi_battery_add() failed"));
1657 "failed"));
1658 goto end; 1699 goto end;
1659 } 1700 }
1660 } 1701 }
@@ -1664,29 +1705,26 @@ static int acpi_sbs_add(struct acpi_device *device)
1664 sbs->handle = device->handle; 1705 sbs->handle = device->handle;
1665 1706
1666 init_timer(&sbs->update_timer); 1707 init_timer(&sbs->update_timer);
1667 if (update_mode == QUEUE_UPDATE_MODE) { 1708 result = acpi_check_update_proc(sbs);
1668 status = acpi_os_execute(OSL_GPE_HANDLER, 1709 if (result)
1669 acpi_sbs_update_queue, sbs); 1710 goto end;
1670 if (status != AE_OK) {
1671 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1672 "acpi_os_execute() failed"));
1673 }
1674 }
1675 sbs->update_time = update_time;
1676 sbs->update_time2 = update_time2;
1677
1678 printk(KERN_INFO PREFIX "%s [%s]\n",
1679 acpi_device_name(device), acpi_device_bid(device));
1680 1711
1681 end: 1712 end:
1713
1714 sbs_mutex_unlock(sbs);
1715
1682 if (result) { 1716 if (result) {
1683 acpi_sbs_remove(device, 0); 1717 remove_result = acpi_sbs_remove(device, 0);
1718 if (remove_result) {
1719 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1720 "acpi_sbs_remove() failed"));
1721 }
1684 } 1722 }
1685 1723
1686 return result; 1724 return result;
1687} 1725}
1688 1726
1689int acpi_sbs_remove(struct acpi_device *device, int type) 1727static int acpi_sbs_remove(struct acpi_device *device, int type)
1690{ 1728{
1691 struct acpi_sbs *sbs; 1729 struct acpi_sbs *sbs;
1692 int id; 1730 int id;
@@ -1695,15 +1733,14 @@ int acpi_sbs_remove(struct acpi_device *device, int type)
1695 return -EINVAL; 1733 return -EINVAL;
1696 } 1734 }
1697 1735
1698 sbs = (struct acpi_sbs *)acpi_driver_data(device); 1736 sbs = acpi_driver_data(device);
1699
1700 if (!sbs) { 1737 if (!sbs) {
1701 return -EINVAL; 1738 return -EINVAL;
1702 } 1739 }
1703 1740
1741 sbs_mutex_lock(sbs);
1742
1704 sbs->zombie = 1; 1743 sbs->zombie = 1;
1705 sbs->update_time = 0;
1706 sbs->update_time2 = 0;
1707 del_timer_sync(&sbs->update_timer); 1744 del_timer_sync(&sbs->update_timer);
1708 acpi_os_wait_events_complete(NULL); 1745 acpi_os_wait_events_complete(NULL);
1709 del_timer_sync(&sbs->update_timer); 1746 del_timer_sync(&sbs->update_timer);
@@ -1714,13 +1751,41 @@ int acpi_sbs_remove(struct acpi_device *device, int type)
1714 1751
1715 acpi_ac_remove(sbs); 1752 acpi_ac_remove(sbs);
1716 1753
1717 acpi_driver_data(device) = NULL; 1754 sbs_mutex_unlock(sbs);
1755
1756 mutex_destroy(&sbs->mutex);
1718 1757
1719 kfree(sbs); 1758 kfree(sbs);
1720 1759
1721 return 0; 1760 return 0;
1722} 1761}
1723 1762
1763static void acpi_sbs_rmdirs(void)
1764{
1765 if (acpi_ac_dir) {
1766 acpi_unlock_ac_dir(acpi_ac_dir);
1767 acpi_ac_dir = NULL;
1768 }
1769 if (acpi_battery_dir) {
1770 acpi_unlock_battery_dir(acpi_battery_dir);
1771 acpi_battery_dir = NULL;
1772 }
1773}
1774
1775static int acpi_sbs_resume(struct acpi_device *device)
1776{
1777 struct acpi_sbs *sbs;
1778
1779 if (!device)
1780 return -EINVAL;
1781
1782 sbs = device->driver_data;
1783
1784 sbs->run_cnt = 0;
1785
1786 return 0;
1787}
1788
1724static int __init acpi_sbs_init(void) 1789static int __init acpi_sbs_init(void)
1725{ 1790{
1726 int result = 0; 1791 int result = 0;
@@ -1728,12 +1793,10 @@ static int __init acpi_sbs_init(void)
1728 if (acpi_disabled) 1793 if (acpi_disabled)
1729 return -ENODEV; 1794 return -ENODEV;
1730 1795
1731 init_MUTEX(&sbs_sem);
1732
1733 if (capacity_mode != DEF_CAPACITY_UNIT 1796 if (capacity_mode != DEF_CAPACITY_UNIT
1734 && capacity_mode != MAH_CAPACITY_UNIT 1797 && capacity_mode != MAH_CAPACITY_UNIT
1735 && capacity_mode != MWH_CAPACITY_UNIT) { 1798 && capacity_mode != MWH_CAPACITY_UNIT) {
1736 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_sbs_init: " 1799 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1737 "invalid capacity_mode = %d", capacity_mode)); 1800 "invalid capacity_mode = %d", capacity_mode));
1738 return -EINVAL; 1801 return -EINVAL;
1739 } 1802 }
@@ -1749,6 +1812,7 @@ static int __init acpi_sbs_init(void)
1749 if (!acpi_battery_dir) { 1812 if (!acpi_battery_dir) {
1750 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 1813 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1751 "acpi_lock_battery_dir() failed")); 1814 "acpi_lock_battery_dir() failed"));
1815 acpi_sbs_rmdirs();
1752 return -ENODEV; 1816 return -ENODEV;
1753 } 1817 }
1754 1818
@@ -1756,6 +1820,7 @@ static int __init acpi_sbs_init(void)
1756 if (result < 0) { 1820 if (result < 0) {
1757 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 1821 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1758 "acpi_bus_register_driver() failed")); 1822 "acpi_bus_register_driver() failed"));
1823 acpi_sbs_rmdirs();
1759 return -ENODEV; 1824 return -ENODEV;
1760 } 1825 }
1761 1826
@@ -1764,13 +1829,9 @@ static int __init acpi_sbs_init(void)
1764 1829
1765static void __exit acpi_sbs_exit(void) 1830static void __exit acpi_sbs_exit(void)
1766{ 1831{
1767
1768 acpi_bus_unregister_driver(&acpi_sbs_driver); 1832 acpi_bus_unregister_driver(&acpi_sbs_driver);
1769 1833
1770 acpi_unlock_ac_dir(acpi_ac_dir); 1834 acpi_sbs_rmdirs();
1771 acpi_ac_dir = NULL;
1772 acpi_unlock_battery_dir(acpi_battery_dir);
1773 acpi_battery_dir = NULL;
1774 1835
1775 return; 1836 return;
1776} 1837}