linux-acpi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* sbs driver
@ 2006-11-28  2:25 Lebedev, Vladimir P
  2007-01-26  9:10 ` Len Brown
  0 siblings, 1 reply; 2+ messages in thread
From: Lebedev, Vladimir P @ 2006-11-28  2:25 UTC (permalink / raw)
  To: Len Brown, Starikovskiy, Alexey Y; +Cc: linux-acpi

[-- Attachment #1: Type: text/plain, Size: 228 bytes --]


Len,

Attached patch contains new release of sbs driver.

The sbs driver was cleaned and restructured. Patch is based on
2.6.19-rc6-mm1. It was tested on Acer 2300 laptop. I suggest add patch
to mm tree.

Vladimir.


[-- Attachment #2: sbs.patch --]
[-- Type: application/octet-stream, Size: 71200 bytes --]

diff -rup linux-2.6.19-rc6-mm1.a/drivers/acpi/i2c_ec.c linux-2.6.19-rc6-mm1.b/drivers/acpi/i2c_ec.c
--- linux-2.6.19-rc6-mm1.a/drivers/acpi/i2c_ec.c	2006-11-28 04:48:52.000000000 +0300
+++ linux-2.6.19-rc6-mm1.b/drivers/acpi/i2c_ec.c	2006-11-28 04:41:48.000000000 +0300
@@ -1,5 +1,5 @@
 /*
- * SMBus driver for ACPI Embedded Controller ($Revision: 1.3 $)
+ * SMBus driver for ACPI Embedded Controller.
  *
  * Copyright (c) 2002, 2005 Ducrot Bruno
  * Copyright (c) 2005 Rich Townsend (tiny hacks & tweaks)
@@ -33,7 +33,7 @@
 
 #define _COMPONENT		ACPI_EC_HC_COMPONENT
 
-ACPI_MODULE_NAME("acpi_smbus")
+ACPI_MODULE_NAME("acpi_i2c_ec")
 
 static int acpi_ec_hc_add(struct acpi_device *device);
 static int acpi_ec_hc_remove(struct acpi_device *device, int type);
@@ -225,8 +225,8 @@ acpi_ec_smb_access(struct i2c_adapter *a
 		break;
 
 	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "EC SMBus adapter: "
-				  "Unsupported transaction %d\n", size));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"unsupported transaction %d\n", size));
 		return (-1);
 	}
 
@@ -245,6 +245,8 @@ acpi_ec_smb_access(struct i2c_adapter *a
 	}
 	if ((~temp[0] & ACPI_EC_SMB_STS_DONE)
 	    || (temp[0] & ACPI_EC_SMB_STS_STATUS)) {
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"transaction %d error\n", size));
 		return (-1);
 	}
 
@@ -327,13 +329,12 @@ static int acpi_ec_hc_add(struct acpi_de
 
 	status = acpi_evaluate_integer(ec_hc->handle, "_EC", NULL, &val);
 	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error obtaining _EC\n"));
+		ACPI_EXCEPTION((AE_INFO, status, "evaluating _EC\n"));
 		kfree(ec_hc);
 		kfree(smbus);
 		return -EIO;
 	}
 
-	smbus->ec = acpi_driver_data(device->parent);
 	smbus->base = (val & 0xff00ull) >> 8;
 	smbus->alert = val & 0xffull;
 
@@ -342,8 +343,8 @@ static int acpi_ec_hc_add(struct acpi_de
 	smbus->adapter.algo_data = smbus;
 
 	if (i2c_add_adapter(&smbus->adapter)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN,
-				  "EC SMBus adapter: Failed to register adapter\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"failed to register adapter\n"));
 		kfree(smbus);
 		kfree(ec_hc);
 		return -EIO;
diff -rup linux-2.6.19-rc6-mm1.a/drivers/acpi/i2c_ec.h linux-2.6.19-rc6-mm1.b/drivers/acpi/i2c_ec.h
--- linux-2.6.19-rc6-mm1.a/drivers/acpi/i2c_ec.h	2006-11-28 04:48:48.000000000 +0300
+++ linux-2.6.19-rc6-mm1.b/drivers/acpi/i2c_ec.h	2006-11-28 04:41:44.000000000 +0300
@@ -1,5 +1,5 @@
 /*
- * SMBus driver for ACPI Embedded Controller ($Revision: 1.2 $)
+ * SMBus driver for ACPI Embedded Controller.
  *
  * Copyright (c) 2002, 2005 Ducrot Bruno
  *
@@ -10,7 +10,6 @@
 
 struct acpi_ec_smbus {
 	struct i2c_adapter adapter;
-	union acpi_ec *ec;
 	int base;
 	int alert;
 };
diff -rup linux-2.6.19-rc6-mm1.a/drivers/acpi/sbs.c linux-2.6.19-rc6-mm1.b/drivers/acpi/sbs.c
--- linux-2.6.19-rc6-mm1.a/drivers/acpi/sbs.c	2006-11-28 04:48:40.000000000 +0300
+++ linux-2.6.19-rc6-mm1.b/drivers/acpi/sbs.c	2006-11-28 04:47:28.000000000 +0300
@@ -1,6 +1,7 @@
 /*
- *  acpi_sbs.c - ACPI Smart Battery System Driver ($Revision: 1.16 $)
+ *  sbs.c - ACPI Smart Battery System Driver.
  *
+ *  Copyright (c) 2006 Vladimir Lebedev <vladimir.p.lebedev@intel.com>
  *  Copyright (c) 2005 Rich Townsend <rhdt@bartol.udel.edu>
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -32,51 +33,63 @@
 #include <linux/acpi.h>
 #include <linux/i2c.h>
 #include <linux/delay.h>
+#include <linux/time.h>
 
 #include "i2c_ec.h"
 
-#define	DEF_CAPACITY_UNIT	3
-#define	MAH_CAPACITY_UNIT	1
-#define	MWH_CAPACITY_UNIT	2
-#define	CAPACITY_UNIT		DEF_CAPACITY_UNIT
-
-#define	REQUEST_UPDATE_MODE	1
-#define	QUEUE_UPDATE_MODE	2
-
-#define	DATA_TYPE_COMMON	0
-#define	DATA_TYPE_INFO		1
-#define	DATA_TYPE_STATE		2
-#define	DATA_TYPE_ALARM		3
-#define	DATA_TYPE_AC_STATE	4
+#define	REQUEST_UPDATE_MODE		1
+#define	TIME_UPDATE_MODE		2
+#define	REQUEST_TIME_UPDATE_MODE	3
+
+#define	UPDATE_MODE			TIME_UPDATE_MODE
+
+#define	MAH_CAPACITY_UNIT		1
+#define	MWH_CAPACITY_UNIT		2
+#define	DEF_CAPACITY_UNIT		3
+#define	CAPACITY_UNIT			DEF_CAPACITY_UNIT
+
+#define	DATA_TYPE_AC_STATE		1
+#define	DATA_TYPE_BAT_INFO		2
+#define	DATA_TYPE_BAT_STATE		3
+#define	DATA_TYPE_BAT_ALARM		4
+#define	DATA_TYPE_COMMON		5
 
-extern struct proc_dir_entry *acpi_lock_ac_dir(void);
-extern struct proc_dir_entry *acpi_lock_battery_dir(void);
-extern void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir);
-extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
+#define	MAX_SBS_BAT			4
+#define	MAX_SMBUS_ERR			1
+
+#define	UPDATE_BAT_INFO_MODE		1
+#define	NON_UPDATE_INFO_MODE		2
 
-#define ACPI_SBS_COMPONENT		0x00080000
+#define	UPDATE_TIME			10
+#define	UPDATE_TIME_AC_CNT		1
+#define	UPDATE_TIME_BAT_CNT		6
+#define	UPDATE_TIME_IO_DELAY		0
+
+#define ACPI_SBS_COMPONENT		0x00060000
 #define ACPI_SBS_CLASS			"sbs"
 #define ACPI_AC_CLASS			"ac_adapter"
-#define ACPI_BATTERY_CLASS		"battery"
+#define ACPI_BAT_CLASS			"battery"
 #define ACPI_SBS_HID			"ACPI0002"
 #define ACPI_SBS_DRIVER_NAME		"ACPI Smart Battery System Driver"
 #define ACPI_SBS_DEVICE_NAME		"Smart Battery System"
 #define ACPI_SBS_FILE_INFO		"info"
 #define ACPI_SBS_FILE_STATE		"state"
 #define ACPI_SBS_FILE_ALARM		"alarm"
-#define ACPI_BATTERY_DIR_NAME		"BAT%i"
-#define ACPI_AC_DIR_NAME		"AC0"
+#define ACPI_BAT_DIR_NAME		"BAT%i"
+#define ACPI_AC_DIR_NAME		"AC"
 #define ACPI_SBC_SMBUS_ADDR		0x9
 #define ACPI_SBSM_SMBUS_ADDR		0xa
 #define ACPI_SB_SMBUS_ADDR		0xb
 #define ACPI_SBS_AC_NOTIFY_STATUS	0x80
-#define ACPI_SBS_BATTERY_NOTIFY_STATUS	0x80
-#define ACPI_SBS_BATTERY_NOTIFY_INFO	0x81
+#define ACPI_SBS_BAT_NOTIFY_STATUS	0x80
+#define ACPI_SBS_BAT_NOTIFY_INFO	0x81
 
 #define _COMPONENT			ACPI_SBS_COMPONENT
 
-#define	MAX_SBS_BAT			4
-#define	MAX_SMBUS_ERR			1
+extern struct proc_dir_entry *acpi_lock_ac_dir(void);
+extern struct proc_dir_entry *acpi_lock_battery_dir(void);
+extern void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir);
+extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_bat_dir);
 
 ACPI_MODULE_NAME("acpi_sbs");
 
@@ -84,30 +97,28 @@ MODULE_AUTHOR("Rich Townsend");
 MODULE_DESCRIPTION("Smart Battery System ACPI interface driver");
 MODULE_LICENSE("GPL");
 
-static struct semaphore sbs_sem;
-
-#define	UPDATE_MODE		QUEUE_UPDATE_MODE
-/* REQUEST_UPDATE_MODE  QUEUE_UPDATE_MODE */
-#define	UPDATE_INFO_MODE	0
-#define	UPDATE_TIME		60
-#define	UPDATE_TIME2		0
+static int acpi_sbs_add(struct acpi_device *device);
+static void acpi_sbs_notify(acpi_handle handle, u32 event, void *data);
+static int acpi_sbs_suspend(struct acpi_device *device, int state);
+static int acpi_sbs_resume(struct acpi_device *device, int state);
+static int acpi_sbs_remove(struct acpi_device *device, int type);
 
 static int capacity_mode = CAPACITY_UNIT;
 static int update_mode = UPDATE_MODE;
-static int update_info_mode = UPDATE_INFO_MODE;
+static int update_bat_info_mode = UPDATE_BAT_INFO_MODE;
+
 static int update_time = UPDATE_TIME;
-static int update_time2 = UPDATE_TIME2;
+static int update_time_ac_cnt = UPDATE_TIME_AC_CNT;
+static int update_time_bat_cnt = UPDATE_TIME_BAT_CNT;
+static int update_time_io_delay = UPDATE_TIME_IO_DELAY;
 
 module_param(capacity_mode, int, 0);
 module_param(update_mode, int, 0);
-module_param(update_info_mode, int, 0);
+module_param(update_bat_info_mode, int, 0);
 module_param(update_time, int, 0);
-module_param(update_time2, int, 0);
-
-static int acpi_sbs_add(struct acpi_device *device);
-static int acpi_sbs_remove(struct acpi_device *device, int type);
-static void acpi_battery_smbus_err_handler(struct acpi_ec_smbus *smbus);
-static void acpi_sbs_update_queue(void *data);
+module_param(update_time_ac_cnt, int, 0);
+module_param(update_time_bat_cnt, int, 0);
+module_param(update_time_io_delay, int, 0);
 
 static struct acpi_driver acpi_sbs_driver = {
 	.name = ACPI_SBS_DRIVER_NAME,
@@ -115,11 +126,18 @@ static struct acpi_driver acpi_sbs_drive
 	.ids = ACPI_SBS_HID,
 	.ops = {
 		.add = acpi_sbs_add,
+		.suspend = acpi_sbs_suspend,
+		.resume = acpi_sbs_resume,
 		.remove = acpi_sbs_remove,
 		},
 };
 
-struct acpi_battery_info {
+struct acpi_ac {
+	int ac_present;
+	unsigned long seconds;
+};
+
+struct acpi_bat_info {
 	int capacity_mode;
 	s16 full_charge_capacity;
 	s16 design_capacity;
@@ -130,58 +148,88 @@ struct acpi_battery_info {
 	char manufacturer_name[I2C_SMBUS_BLOCK_MAX + 3];
 	char device_name[I2C_SMBUS_BLOCK_MAX + 3];
 	char device_chemistry[I2C_SMBUS_BLOCK_MAX + 3];
+	unsigned long seconds;
 };
 
-struct acpi_battery_state {
+struct acpi_bat_state {
 	s16 voltage;
 	s16 amperage;
 	s16 remaining_capacity;
-	s16 average_time_to_empty;
-	s16 average_time_to_full;
-	s16 battery_status;
+	s16 bat_status;
+	unsigned long seconds;
 };
 
-struct acpi_battery_alarm {
+struct acpi_bat_alarm {
 	s16 remaining_capacity;
+	unsigned long seconds;
 };
 
-struct acpi_battery {
+struct acpi_bat {
 	int alive;
-	int battery_present;
 	int id;
 	int init_state;
+	int bat_present;
 	struct acpi_sbs *sbs;
-	struct acpi_battery_info info;
-	struct acpi_battery_state state;
-	struct acpi_battery_alarm alarm;
-	struct proc_dir_entry *battery_entry;
+	struct acpi_bat_info info;
+	struct acpi_bat_state state;
+	struct acpi_bat_alarm alarm;
+	struct proc_dir_entry *bat_entry;
 };
 
 struct acpi_sbs {
 	acpi_handle handle;
 	struct acpi_device *device;
 	struct acpi_ec_smbus *smbus;
+	struct mutex mutex;
 	int sbsm_present;
 	int sbsm_batteries_supported;
-	int ac_present;
 	struct proc_dir_entry *ac_entry;
-	struct acpi_battery battery[MAX_SBS_BAT];
-	int update_info_mode;
+	struct acpi_ac ac;
+	struct acpi_bat bat[MAX_SBS_BAT];
 	int zombie;
 	int update_time;
-	int update_time2;
+	int update_time_io_delay;
 	struct timer_list update_timer;
+	int run_cnt;
 };
 
 static void acpi_update_delay(struct acpi_sbs *sbs);
 static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type);
+static void acpi_bat_smbus_err_handler(struct acpi_sbs *sbs);
+static void acpi_sbs_update_time(void *data);
 
 /* --------------------------------------------------------------------------
                                SMBus Communication
    -------------------------------------------------------------------------- */
 
-static void acpi_battery_smbus_err_handler(struct acpi_ec_smbus *smbus)
+#define sbs_zombie(sbs) sbs_zombie_func(sbs, __FILE__, __LINE__)
+
+static int sbs_zombie_func(struct acpi_sbs *sbs, char *file, int line)
+{
+	if (sbs->zombie) {
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "I am ZOMBIE: %s %d\n", file,
+				  line));
+	}
+	return (sbs->zombie);
+}
+
+static int sbs_mutex_lock(struct acpi_sbs *sbs)
+{
+	if (sbs_zombie(sbs)) {
+		return -ENODEV;
+	}
+	mutex_lock(&sbs->mutex);
+	return 0;
+}
+
+static void sbs_mutex_unlock(struct acpi_sbs *sbs)
 {
+	mutex_unlock(&sbs->mutex);
+}
+
+static void acpi_bat_smbus_err_handler(struct acpi_sbs *sbs)
+{
+	struct acpi_ec_smbus *smbus = sbs->smbus;
 	union i2c_smbus_data data;
 	int result = 0;
 	char *err_str;
@@ -189,6 +237,8 @@ static void acpi_battery_smbus_err_handl
 
 	data.word = 0;
 
+	acpi_update_delay(sbs);
+
 	result = smbus->adapter.algo->
 	    smbus_xfer(&smbus->adapter,
 		       ACPI_SB_SMBUS_ADDR,
@@ -224,34 +274,32 @@ static void acpi_battery_smbus_err_handl
 	default:
 		err_str = "unrecognized error";
 	}
-	ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-			  "%s: ret %i, err %i\n", err_str, result, err_number));
+	ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+			"%s: ret %i, err %i\n", err_str, result, err_number));
 }
 
 static int
-acpi_sbs_smbus_read_word(struct acpi_ec_smbus *smbus, int addr, int func,
-			 u16 * word,
-			 void (*err_handler) (struct acpi_ec_smbus * smbus))
+acpi_sbs_smbus_read_word(struct acpi_sbs *sbs, int addr, int func, u16 * word,
+			 void (*err_handler) (struct acpi_sbs * sbs))
 {
+	struct acpi_ec_smbus *smbus = sbs->smbus;
 	union i2c_smbus_data data;
 	int result = 0;
 	int i;
 
-	if (err_handler == NULL) {
-		err_handler = acpi_battery_smbus_err_handler;
-	}
-
 	for (i = 0; i < MAX_SMBUS_ERR; i++) {
+		acpi_update_delay(sbs);
 		result =
 		    smbus->adapter.algo->smbus_xfer(&smbus->adapter, addr, 0,
 						    I2C_SMBUS_READ, func,
 						    I2C_SMBUS_WORD_DATA, &data);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "try %i: smbus->adapter.algo->smbus_xfer() failed\n",
-					  i));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"try %i, result %d, "
+					"smbus->adapter.algo->smbus_xfer() "
+					"failed\n", i, result));
 			if (err_handler) {
-				err_handler(smbus);
+				err_handler(sbs);
 			}
 		} else {
 			*word = data.word;
@@ -263,30 +311,28 @@ acpi_sbs_smbus_read_word(struct acpi_ec_
 }
 
 static int
-acpi_sbs_smbus_read_str(struct acpi_ec_smbus *smbus, int addr, int func,
-			char *str,
-			void (*err_handler) (struct acpi_ec_smbus * smbus))
+acpi_sbs_smbus_read_str(struct acpi_sbs *sbs, int addr, int func, char *str,
+			void (*err_handler) (struct acpi_sbs * sbs))
 {
+	struct acpi_ec_smbus *smbus = sbs->smbus;
 	union i2c_smbus_data data;
 	int result = 0;
 	int i;
 
-	if (err_handler == NULL) {
-		err_handler = acpi_battery_smbus_err_handler;
-	}
-
 	for (i = 0; i < MAX_SMBUS_ERR; i++) {
+		acpi_update_delay(sbs);
 		result =
 		    smbus->adapter.algo->smbus_xfer(&smbus->adapter, addr, 0,
 						    I2C_SMBUS_READ, func,
 						    I2C_SMBUS_BLOCK_DATA,
 						    &data);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "try %i: smbus->adapter.algo->smbus_xfer() failed\n",
-					  i));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"try %i, result %d, "
+					"smbus->adapter.algo->smbus_xfer() "
+					"failed\n", i, result));
 			if (err_handler) {
-				err_handler(smbus);
+				err_handler(sbs);
 			}
 		} else {
 			strncpy(str, (const char *)data.block + 1,
@@ -300,31 +346,29 @@ acpi_sbs_smbus_read_str(struct acpi_ec_s
 }
 
 static int
-acpi_sbs_smbus_write_word(struct acpi_ec_smbus *smbus, int addr, int func,
-			  int word,
-			  void (*err_handler) (struct acpi_ec_smbus * smbus))
+acpi_sbs_smbus_write_word(struct acpi_sbs *sbs, int addr, int func, int word,
+			  void (*err_handler) (struct acpi_sbs * sbs))
 {
+	struct acpi_ec_smbus *smbus = sbs->smbus;
 	union i2c_smbus_data data;
 	int result = 0;
 	int i;
 
-	if (err_handler == NULL) {
-		err_handler = acpi_battery_smbus_err_handler;
-	}
-
 	data.word = word;
 
 	for (i = 0; i < MAX_SMBUS_ERR; i++) {
+		acpi_update_delay(sbs);
 		result =
 		    smbus->adapter.algo->smbus_xfer(&smbus->adapter, addr, 0,
 						    I2C_SMBUS_WRITE, func,
 						    I2C_SMBUS_WORD_DATA, &data);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "try %i: smbus->adapter.algo"
-					  "->smbus_xfer() failed\n", i));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"try %i, result %d, "
+					"smbus->adapter.algo->smbus_xfer() "
+					"failed\n", i, result));
 			if (err_handler) {
-				err_handler(smbus);
+				err_handler(sbs);
 			}
 		} else {
 			break;
@@ -361,66 +405,60 @@ static int acpi_sbs_generate_event(struc
 	return result;
 }
 
-static int acpi_battery_get_present(struct acpi_battery *battery)
+static int acpi_bat_get_present(struct acpi_bat *bat)
 {
 	s16 state;
 	int result = 0;
 	int is_present = 0;
 
-	result = acpi_sbs_smbus_read_word(battery->sbs->smbus,
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "acpi_bat_get_present\n"));
+
+	result = acpi_sbs_smbus_read_word(bat->sbs,
 					  ACPI_SBSM_SMBUS_ADDR, 0x01,
 					  &state, NULL);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_smbus_read_word() failed"));
 	}
 	if (!result) {
-		is_present = (state & 0x000f) & (1 << battery->id);
+		is_present = (state & 0x000f) & (1 << bat->id);
 	}
-	battery->battery_present = is_present;
+	bat->bat_present = is_present;
 
 	return result;
 }
 
-static int acpi_battery_is_present(struct acpi_battery *battery)
-{
-	return (battery->battery_present);
-}
-
-static int acpi_ac_is_present(struct acpi_sbs *sbs)
+static int acpi_bat_select(struct acpi_bat *bat)
 {
-	return (sbs->ac_present);
-}
-
-static int acpi_battery_select(struct acpi_battery *battery)
-{
-	struct acpi_ec_smbus *smbus = battery->sbs->smbus;
+	struct acpi_sbs *sbs = bat->sbs;
 	int result = 0;
 	s16 state;
 	int foo;
 
-	if (battery->sbs->sbsm_present) {
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "acpi_bat_select\n"));
+
+	if (sbs->sbsm_present) {
 
 		/* Take special care not to knobble other nibbles of
 		 * state (aka selector_state), since
 		 * it causes charging to halt on SBSELs */
 
 		result =
-		    acpi_sbs_smbus_read_word(smbus, ACPI_SBSM_SMBUS_ADDR, 0x01,
+		    acpi_sbs_smbus_read_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x01,
 					     &state, NULL);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_smbus_read_word() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbs_smbus_read_word() failed\n"));
 			goto end;
 		}
 
-		foo = (state & 0x0fff) | (1 << (battery->id + 12));
+		foo = (state & 0x0fff) | (1 << (bat->id + 12));
 		result =
-		    acpi_sbs_smbus_write_word(smbus, ACPI_SBSM_SMBUS_ADDR, 0x01,
+		    acpi_sbs_smbus_write_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x01,
 					      foo, NULL);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_smbus_write_word() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbs_smbus_write_word() failed\n"));
 			goto end;
 		}
 	}
@@ -431,136 +469,143 @@ static int acpi_battery_select(struct ac
 
 static int acpi_sbsm_get_info(struct acpi_sbs *sbs)
 {
-	struct acpi_ec_smbus *smbus = sbs->smbus;
 	int result = 0;
-	s16 battery_system_info;
+	s16 bat_system_info;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "acpi_sbsm_get_info\n"));
 
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SBSM_SMBUS_ADDR, 0x04,
-					  &battery_system_info, NULL);
+	result = acpi_sbs_smbus_read_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x04,
+					  &bat_system_info, NULL);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_smbus_read_word() failed\n"));
 		goto end;
 	}
 
-	sbs->sbsm_batteries_supported = battery_system_info & 0x000f;
+	sbs->sbsm_batteries_supported = bat_system_info & 0x000f;
 
       end:
 
 	return result;
 }
 
-static int acpi_battery_get_info(struct acpi_battery *battery)
+static int acpi_bat_get_info(struct acpi_bat *bat)
 {
-	struct acpi_ec_smbus *smbus = battery->sbs->smbus;
+	struct acpi_sbs *sbs = bat->sbs;
 	int result = 0;
-	s16 battery_mode;
+	s16 bat_mode;
 	s16 specification_info;
 
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x03,
-					  &battery_mode,
-					  &acpi_battery_smbus_err_handler);
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "acpi_bat_get_info\n"));
+
+	result = acpi_sbs_smbus_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x03,
+					  &bat_mode,
+					  &acpi_bat_smbus_err_handler);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_smbus_read_word() failed\n"));
 		goto end;
 	}
-	battery->info.capacity_mode = (battery_mode & 0x8000) >> 15;
+	bat->info.capacity_mode = (bat_mode & 0x8000) >> 15;
 
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x10,
-					  &battery->info.full_charge_capacity,
-					  &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_smbus_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x10,
+					  &bat->info.full_charge_capacity,
+					  &acpi_bat_smbus_err_handler);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_smbus_read_word() failed\n"));
 		goto end;
 	}
 
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x18,
-					  &battery->info.design_capacity,
-					  &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_smbus_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x18,
+					  &bat->info.design_capacity,
+					  &acpi_bat_smbus_err_handler);
 
 	if (result) {
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_smbus_read_word() failed\n"));
 		goto end;
 	}
 
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x19,
-					  &battery->info.design_voltage,
-					  &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_smbus_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x19,
+					  &bat->info.design_voltage,
+					  &acpi_bat_smbus_err_handler);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_smbus_read_word() failed\n"));
 		goto end;
 	}
 
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x1a,
+	result = acpi_sbs_smbus_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1a,
 					  &specification_info,
-					  &acpi_battery_smbus_err_handler);
+					  &acpi_bat_smbus_err_handler);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_smbus_read_word() failed\n"));
 		goto end;
 	}
 
 	switch ((specification_info & 0x0f00) >> 8) {
 	case 1:
-		battery->info.vscale = 10;
+		bat->info.vscale = 10;
 		break;
 	case 2:
-		battery->info.vscale = 100;
+		bat->info.vscale = 100;
 		break;
 	case 3:
-		battery->info.vscale = 1000;
+		bat->info.vscale = 1000;
 		break;
 	default:
-		battery->info.vscale = 1;
+		bat->info.vscale = 1;
 	}
 
 	switch ((specification_info & 0xf000) >> 12) {
 	case 1:
-		battery->info.ipscale = 10;
+		bat->info.ipscale = 10;
 		break;
 	case 2:
-		battery->info.ipscale = 100;
+		bat->info.ipscale = 100;
 		break;
 	case 3:
-		battery->info.ipscale = 1000;
+		bat->info.ipscale = 1000;
 		break;
 	default:
-		battery->info.ipscale = 1;
+		bat->info.ipscale = 1;
 	}
 
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x1c,
-					  &battery->info.serial_number,
-					  &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_smbus_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1c,
+					  &bat->info.serial_number,
+					  &acpi_bat_smbus_err_handler);
 	if (result) {
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_smbus_read_word() failed\n"));
 		goto end;
 	}
 
-	result = acpi_sbs_smbus_read_str(smbus, ACPI_SB_SMBUS_ADDR, 0x20,
-					 battery->info.manufacturer_name,
-					 &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_smbus_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x20,
+					 bat->info.manufacturer_name,
+					 &acpi_bat_smbus_err_handler);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_str() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_smbus_read_str() failed\n"));
 		goto end;
 	}
 
-	result = acpi_sbs_smbus_read_str(smbus, ACPI_SB_SMBUS_ADDR, 0x21,
-					 battery->info.device_name,
-					 &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_smbus_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x21,
+					 bat->info.device_name,
+					 &acpi_bat_smbus_err_handler);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_str() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_smbus_read_str() failed\n"));
 		goto end;
 	}
 
-	result = acpi_sbs_smbus_read_str(smbus, ACPI_SB_SMBUS_ADDR, 0x22,
-					 battery->info.device_chemistry,
-					 &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_smbus_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x22,
+					 bat->info.device_chemistry,
+					 &acpi_bat_smbus_err_handler);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_str() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_smbus_read_str() failed\n"));
 		goto end;
 	}
 
@@ -570,118 +615,88 @@ static int acpi_battery_get_info(struct 
 
 static void acpi_update_delay(struct acpi_sbs *sbs)
 {
-	if (sbs->zombie) {
-		return;
-	}
-	if (sbs->update_time2 > 0) {
-		msleep(sbs->update_time2 * 1000);
+	if (sbs->update_time_io_delay > 0) {
+		msleep(sbs->update_time_io_delay * 1000);
 	}
 }
 
-static int acpi_battery_get_state(struct acpi_battery *battery)
+static int acpi_bat_get_state(struct acpi_bat *bat)
 {
-	struct acpi_ec_smbus *smbus = battery->sbs->smbus;
+	struct acpi_sbs *sbs = bat->sbs;
 	int result = 0;
 
-	acpi_update_delay(battery->sbs);
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x09,
-					  &battery->state.voltage,
-					  &acpi_battery_smbus_err_handler);
-	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
-		goto end;
-	}
-
-	acpi_update_delay(battery->sbs);
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x0a,
-					  &battery->state.amperage,
-					  &acpi_battery_smbus_err_handler);
-	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
-		goto end;
-	}
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "acpi_bat_get_state\n"));
 
-	acpi_update_delay(battery->sbs);
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x0f,
-					  &battery->state.remaining_capacity,
-					  &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_smbus_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x09,
+					  &bat->state.voltage,
+					  &acpi_bat_smbus_err_handler);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_smbus_read_word() failed\n"));
 		goto end;
 	}
 
-	acpi_update_delay(battery->sbs);
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x12,
-					  &battery->state.average_time_to_empty,
-					  &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_smbus_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0a,
+					  &bat->state.amperage,
+					  &acpi_bat_smbus_err_handler);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_smbus_read_word() failed\n"));
 		goto end;
 	}
 
-	acpi_update_delay(battery->sbs);
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x13,
-					  &battery->state.average_time_to_full,
-					  &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_smbus_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0f,
+					  &bat->state.remaining_capacity,
+					  &acpi_bat_smbus_err_handler);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_smbus_read_word() failed\n"));
 		goto end;
 	}
 
-	acpi_update_delay(battery->sbs);
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x16,
-					  &battery->state.battery_status,
-					  &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_smbus_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x16,
+					  &bat->state.bat_status,
+					  &acpi_bat_smbus_err_handler);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_smbus_read_word() failed\n"));
 		goto end;
 	}
 
-	acpi_update_delay(battery->sbs);
-
       end:
 	return result;
 }
 
-static int acpi_battery_get_alarm(struct acpi_battery *battery)
+static int acpi_bat_get_alarm(struct acpi_bat *bat)
 {
-	struct acpi_ec_smbus *smbus = battery->sbs->smbus;
+	struct acpi_sbs *sbs = bat->sbs;
 	int result = 0;
 
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x01,
-					  &battery->alarm.remaining_capacity,
-					  &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_smbus_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01,
+					  &bat->alarm.remaining_capacity,
+					  &acpi_bat_smbus_err_handler);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_smbus_read_word() failed\n"));
 		goto end;
 	}
 
-	acpi_update_delay(battery->sbs);
-
       end:
 
 	return result;
 }
 
-static int acpi_battery_set_alarm(struct acpi_battery *battery,
-				  unsigned long alarm)
+static int acpi_bat_set_alarm(struct acpi_bat *bat, unsigned long alarm)
 {
-	struct acpi_ec_smbus *smbus = battery->sbs->smbus;
+	struct acpi_sbs *sbs = bat->sbs;
 	int result = 0;
-	s16 battery_mode;
+	s16 bat_mode;
 	int foo;
 
-	result = acpi_battery_select(battery);
+	result = acpi_bat_select(bat);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_battery_select() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_bat_select() failed\n"));
 		goto end;
 	}
 
@@ -689,33 +704,32 @@ static int acpi_battery_set_alarm(struct
 
 	if (alarm > 0) {
 		result =
-		    acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x03,
-					     &battery_mode,
-					     &acpi_battery_smbus_err_handler);
+		    acpi_sbs_smbus_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x03,
+					     &bat_mode,
+					     &acpi_bat_smbus_err_handler);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_smbus_read_word() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbs_smbus_read_word() failed\n"));
 			goto end;
 		}
 
 		result =
-		    acpi_sbs_smbus_write_word(smbus, ACPI_SB_SMBUS_ADDR, 0x01,
-					      battery_mode & 0xbfff,
-					      &acpi_battery_smbus_err_handler);
+		    acpi_sbs_smbus_write_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01,
+					      bat_mode & 0xbfff,
+					      &acpi_bat_smbus_err_handler);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_smbus_write_word() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbs_smbus_write_word() failed\n"));
 			goto end;
 		}
 	}
 
-	foo = alarm / (battery->info.capacity_mode ? 10 : 1);
-	result = acpi_sbs_smbus_write_word(smbus, ACPI_SB_SMBUS_ADDR, 0x01,
-					   foo,
-					   &acpi_battery_smbus_err_handler);
+	foo = alarm / (bat->info.capacity_mode ? 10 : 1);
+	result = acpi_sbs_smbus_write_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01,
+					   foo, &acpi_bat_smbus_err_handler);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_write_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_smbus_write_word() failed\n"));
 		goto end;
 	}
 
@@ -724,44 +738,45 @@ static int acpi_battery_set_alarm(struct
 	return result;
 }
 
-static int acpi_battery_set_mode(struct acpi_battery *battery)
+static int acpi_bat_set_mode(struct acpi_bat *bat)
 {
+	struct acpi_sbs *sbs = bat->sbs;
 	int result = 0;
-	s16 battery_mode;
+	s16 bat_mode;
 
 	if (capacity_mode == DEF_CAPACITY_UNIT) {
 		goto end;
 	}
 
-	result = acpi_sbs_smbus_read_word(battery->sbs->smbus,
+	result = acpi_sbs_smbus_read_word(sbs,
 					  ACPI_SB_SMBUS_ADDR, 0x03,
-					  &battery_mode, NULL);
+					  &bat_mode, NULL);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_smbus_read_word() failed\n"));
 		goto end;
 	}
 
 	if (capacity_mode == MAH_CAPACITY_UNIT) {
-		battery_mode &= 0x7fff;
+		bat_mode &= 0x7fff;
 	} else {
-		battery_mode |= 0x8000;
+		bat_mode |= 0x8000;
 	}
-	result = acpi_sbs_smbus_write_word(battery->sbs->smbus,
+	result = acpi_sbs_smbus_write_word(sbs,
 					   ACPI_SB_SMBUS_ADDR, 0x03,
-					   battery_mode, NULL);
+					   bat_mode, NULL);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_write_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_smbus_write_word() failed\n"));
 		goto end;
 	}
 
-	result = acpi_sbs_smbus_read_word(battery->sbs->smbus,
+	result = acpi_sbs_smbus_read_word(sbs,
 					  ACPI_SB_SMBUS_ADDR, 0x03,
-					  &battery_mode, NULL);
+					  &bat_mode, NULL);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_smbus_read_word() failed\n"));
 		goto end;
 	}
 
@@ -769,42 +784,42 @@ static int acpi_battery_set_mode(struct 
 	return result;
 }
 
-static int acpi_battery_init(struct acpi_battery *battery)
+static int acpi_bat_init(struct acpi_bat *bat)
 {
 	int result = 0;
 
-	result = acpi_battery_select(battery);
+	result = acpi_bat_select(bat);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_battery_init() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_bat_select() failed\n"));
 		goto end;
 	}
 
-	result = acpi_battery_set_mode(battery);
+	result = acpi_bat_set_mode(bat);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_battery_set_mode() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_bat_set_mode() failed\n"));
 		goto end;
 	}
 
-	result = acpi_battery_get_info(battery);
+	result = acpi_bat_get_info(bat);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_battery_get_info() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_bat_get_info() failed\n"));
 		goto end;
 	}
 
-	result = acpi_battery_get_state(battery);
+	result = acpi_bat_get_state(bat);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_battery_get_state() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_bat_get_state() failed\n"));
 		goto end;
 	}
 
-	result = acpi_battery_get_alarm(battery);
+	result = acpi_bat_get_alarm(bat);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_battery_get_alarm() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_bat_get_alarm() failed\n"));
 		goto end;
 	}
 
@@ -814,20 +829,21 @@ static int acpi_battery_init(struct acpi
 
 static int acpi_ac_get_present(struct acpi_sbs *sbs)
 {
-	struct acpi_ec_smbus *smbus = sbs->smbus;
 	int result = 0;
 	s16 charger_status;
 
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SBC_SMBUS_ADDR, 0x13,
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "acpi_ac_get_present\n"));
+
+	result = acpi_sbs_smbus_read_word(sbs, ACPI_SBC_SMBUS_ADDR, 0x13,
 					  &charger_status, NULL);
 
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_smbus_read_word() failed\n"));
 		goto end;
 	}
 
-	sbs->ac_present = (charger_status & 0x8000) >> 15;
+	sbs->ac.ac_present = (charger_status & 0x8000) >> 15;
 
       end:
 
@@ -853,8 +869,8 @@ acpi_sbs_generic_add_fs(struct proc_dir_
 	if (!*dir) {
 		*dir = proc_mkdir(dir_name, parent_dir);
 		if (!*dir) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "proc_mkdir() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"proc_mkdir() failed\n"));
 			return -ENODEV;
 		}
 		(*dir)->owner = THIS_MODULE;
@@ -864,8 +880,8 @@ acpi_sbs_generic_add_fs(struct proc_dir_
 	if (info_fops) {
 		entry = create_proc_entry(ACPI_SBS_FILE_INFO, S_IRUGO, *dir);
 		if (!entry) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "create_proc_entry() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"create_proc_entry() failed\n"));
 		} else {
 			entry->proc_fops = info_fops;
 			entry->data = data;
@@ -877,8 +893,8 @@ acpi_sbs_generic_add_fs(struct proc_dir_
 	if (state_fops) {
 		entry = create_proc_entry(ACPI_SBS_FILE_STATE, S_IRUGO, *dir);
 		if (!entry) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "create_proc_entry() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"create_proc_entry() failed\n"));
 		} else {
 			entry->proc_fops = state_fops;
 			entry->data = data;
@@ -890,8 +906,8 @@ acpi_sbs_generic_add_fs(struct proc_dir_
 	if (alarm_fops) {
 		entry = create_proc_entry(ACPI_SBS_FILE_ALARM, S_IRUGO, *dir);
 		if (!entry) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "create_proc_entry() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"create_proc_entry() failed\n"));
 		} else {
 			entry->proc_fops = alarm_fops;
 			entry->data = data;
@@ -919,224 +935,256 @@ acpi_sbs_generic_remove_fs(struct proc_d
 
 /* Smart Battery Interface */
 
-static struct proc_dir_entry *acpi_battery_dir = NULL;
+static struct proc_dir_entry *acpi_bat_dir = NULL;
 
-static int acpi_battery_read_info(struct seq_file *seq, void *offset)
+static int acpi_bat_read_info(struct seq_file *seq, void *offset)
 {
-	struct acpi_battery *battery = (struct acpi_battery *)seq->private;
+	struct acpi_bat *bat = seq->private;
+	struct acpi_sbs *sbs = bat->sbs;
 	int cscale;
 	int result = 0;
+	unsigned long seconds;
+	int call_update = 0;
 
-	if (battery->sbs->zombie) {
+	if (sbs_mutex_lock(sbs)) {
 		return -ENODEV;
 	}
 
-	down(&sbs_sem);
-
 	if (update_mode == REQUEST_UPDATE_MODE) {
-		result = acpi_sbs_update_run(battery->sbs, DATA_TYPE_INFO);
+		call_update = 1;
+	} else if (update_mode == REQUEST_TIME_UPDATE_MODE) {
+		seconds = get_seconds();
+		if (seconds - bat->info.seconds >=
+		    update_time * update_time_bat_cnt) {
+			bat->info.seconds = seconds;
+			call_update = 1;
+		}
+	}
+
+	if (call_update) {
+		result = acpi_sbs_update_run(sbs, DATA_TYPE_BAT_INFO);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_update_run() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbs_update_run() failed\n"));
 		}
 	}
 
-	if (acpi_battery_is_present(battery)) {
+	if (bat->bat_present) {
 		seq_printf(seq, "present:                 yes\n");
 	} else {
 		seq_printf(seq, "present:                 no\n");
 		goto end;
 	}
 
-	if (battery->info.capacity_mode) {
-		cscale = battery->info.vscale * battery->info.ipscale;
+	if (bat->info.capacity_mode) {
+		cscale = bat->info.vscale * bat->info.ipscale;
 	} else {
-		cscale = battery->info.ipscale;
+		cscale = bat->info.ipscale;
 	}
-	seq_printf(seq, "design capacity:         %i%s",
-		   battery->info.design_capacity * cscale,
-		   battery->info.capacity_mode ? "0 mWh\n" : " mAh\n");
-
-	seq_printf(seq, "last full capacity:      %i%s",
-		   battery->info.full_charge_capacity * cscale,
-		   battery->info.capacity_mode ? "0 mWh\n" : " mAh\n");
+	seq_printf(seq, "design capacity:         %i%s\n",
+		   bat->info.design_capacity * cscale,
+		   bat->info.capacity_mode ? "0 mWh" : " mAh");
+
+	seq_printf(seq, "last full capacity:      %i%s\n",
+		   bat->info.full_charge_capacity * cscale,
+		   bat->info.capacity_mode ? "0 mWh" : " mAh");
 
 	seq_printf(seq, "battery technology:      rechargeable\n");
 
 	seq_printf(seq, "design voltage:          %i mV\n",
-		   battery->info.design_voltage * battery->info.vscale);
+		   bat->info.design_voltage * bat->info.vscale);
 
 	seq_printf(seq, "design capacity warning: unknown\n");
 	seq_printf(seq, "design capacity low:     unknown\n");
 	seq_printf(seq, "capacity granularity 1:  unknown\n");
 	seq_printf(seq, "capacity granularity 2:  unknown\n");
 
-	seq_printf(seq, "model number:            %s\n",
-		   battery->info.device_name);
+	seq_printf(seq, "model number:            %s\n", bat->info.device_name);
 
 	seq_printf(seq, "serial number:           %i\n",
-		   battery->info.serial_number);
+		   bat->info.serial_number);
 
 	seq_printf(seq, "battery type:            %s\n",
-		   battery->info.device_chemistry);
+		   bat->info.device_chemistry);
 
 	seq_printf(seq, "OEM info:                %s\n",
-		   battery->info.manufacturer_name);
+		   bat->info.manufacturer_name);
 
       end:
 
-	up(&sbs_sem);
+	sbs_mutex_unlock(sbs);
 
 	return result;
 }
 
-static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
+static int acpi_bat_info_open_fs(struct inode *inode, struct file *file)
 {
-	return single_open(file, acpi_battery_read_info, PDE(inode)->data);
+	return single_open(file, acpi_bat_read_info, PDE(inode)->data);
 }
 
-static int acpi_battery_read_state(struct seq_file *seq, void *offset)
+static int acpi_bat_read_state(struct seq_file *seq, void *offset)
 {
-	struct acpi_battery *battery = (struct acpi_battery *)seq->private;
+	struct acpi_bat *bat = seq->private;
+	struct acpi_sbs *sbs = bat->sbs;
 	int result = 0;
 	int cscale;
 	int foo;
+	unsigned long seconds;
+	int call_update = 0;
 
-	if (battery->sbs->zombie) {
+	if (sbs_mutex_lock(sbs)) {
 		return -ENODEV;
 	}
 
-	down(&sbs_sem);
-
 	if (update_mode == REQUEST_UPDATE_MODE) {
-		result = acpi_sbs_update_run(battery->sbs, DATA_TYPE_STATE);
+		call_update = 1;
+	} else if (update_mode == REQUEST_TIME_UPDATE_MODE) {
+		seconds = get_seconds();
+		if (seconds - bat->state.seconds >=
+		    update_time * update_time_bat_cnt) {
+			bat->state.seconds = seconds;
+			call_update = 1;
+		}
+	}
+
+	if (call_update) {
+		result = acpi_sbs_update_run(sbs, DATA_TYPE_BAT_STATE);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_update_run() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbs_update_run() failed\n"));
 		}
 	}
 
-	if (acpi_battery_is_present(battery)) {
+	if (bat->bat_present) {
 		seq_printf(seq, "present:                 yes\n");
 	} else {
 		seq_printf(seq, "present:                 no\n");
 		goto end;
 	}
 
-	if (battery->info.capacity_mode) {
-		cscale = battery->info.vscale * battery->info.ipscale;
+	if (bat->info.capacity_mode) {
+		cscale = bat->info.vscale * bat->info.ipscale;
 	} else {
-		cscale = battery->info.ipscale;
+		cscale = bat->info.ipscale;
 	}
 
-	if (battery->state.battery_status & 0x0010) {
+	if (bat->state.bat_status & 0x0010) {
 		seq_printf(seq, "capacity state:          critical\n");
 	} else {
 		seq_printf(seq, "capacity state:          ok\n");
 	}
-	if (battery->state.amperage < 0) {
+
+	foo = (s16) bat->state.amperage * cscale;
+	if (bat->info.capacity_mode) {
+		foo = foo * bat->info.design_voltage / 1000;
+	}
+	if (bat->state.amperage < 0) {
 		seq_printf(seq, "charging state:          discharging\n");
-		foo = battery->state.remaining_capacity * cscale * 60 /
-		    (battery->state.average_time_to_empty == 0 ? 1 :
-		     battery->state.average_time_to_empty);
-		seq_printf(seq, "present rate:            %i%s\n",
-			   foo, battery->info.capacity_mode ? "0 mW" : " mA");
-	} else if (battery->state.amperage > 0) {
+		seq_printf(seq, "present rate:            %d %s\n",
+			   -foo, bat->info.capacity_mode ? "mW" : "mA");
+	} else if (bat->state.amperage > 0) {
 		seq_printf(seq, "charging state:          charging\n");
-		foo = (battery->info.full_charge_capacity -
-		       battery->state.remaining_capacity) * cscale * 60 /
-		    (battery->state.average_time_to_full == 0 ? 1 :
-		     battery->state.average_time_to_full);
-		seq_printf(seq, "present rate:            %i%s\n",
-			   foo, battery->info.capacity_mode ? "0 mW" : " mA");
+		seq_printf(seq, "present rate:            %d %s\n",
+			   foo, bat->info.capacity_mode ? "mW" : "mA");
 	} else {
 		seq_printf(seq, "charging state:          charged\n");
 		seq_printf(seq, "present rate:            0 %s\n",
-			   battery->info.capacity_mode ? "mW" : "mA");
+			   bat->info.capacity_mode ? "mW" : "mA");
 	}
 
-	seq_printf(seq, "remaining capacity:      %i%s",
-		   battery->state.remaining_capacity * cscale,
-		   battery->info.capacity_mode ? "0 mWh\n" : " mAh\n");
+	seq_printf(seq, "remaining capacity:      %i%s\n",
+		   bat->state.remaining_capacity * cscale,
+		   bat->info.capacity_mode ? "0 mWh" : " mAh");
 
 	seq_printf(seq, "present voltage:         %i mV\n",
-		   battery->state.voltage * battery->info.vscale);
+		   bat->state.voltage * bat->info.vscale);
 
       end:
 
-	up(&sbs_sem);
+	sbs_mutex_unlock(sbs);
 
 	return result;
 }
 
-static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
+static int acpi_bat_state_open_fs(struct inode *inode, struct file *file)
 {
-	return single_open(file, acpi_battery_read_state, PDE(inode)->data);
+	return single_open(file, acpi_bat_read_state, PDE(inode)->data);
 }
 
-static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
+static int acpi_bat_read_alarm(struct seq_file *seq, void *offset)
 {
-	struct acpi_battery *battery = (struct acpi_battery *)seq->private;
+	struct acpi_bat *bat = seq->private;
+	struct acpi_sbs *sbs = bat->sbs;
 	int result = 0;
 	int cscale;
+	unsigned long seconds;
+	int call_update = 0;
 
-	if (battery->sbs->zombie) {
+	if (sbs_mutex_lock(sbs)) {
 		return -ENODEV;
 	}
 
-	down(&sbs_sem);
-
 	if (update_mode == REQUEST_UPDATE_MODE) {
-		result = acpi_sbs_update_run(battery->sbs, DATA_TYPE_ALARM);
+		call_update = 1;
+	} else if (update_mode == REQUEST_TIME_UPDATE_MODE) {
+		seconds = get_seconds();
+		if (seconds - bat->alarm.seconds >=
+		    update_time * update_time_bat_cnt) {
+			bat->alarm.seconds = seconds;
+			call_update = 1;
+		}
+	}
+
+	if (call_update) {
+		result = acpi_sbs_update_run(sbs, DATA_TYPE_BAT_ALARM);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_update_run() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbs_update_run() failed\n"));
 		}
 	}
 
-	if (!acpi_battery_is_present(battery)) {
+	if (!bat->bat_present) {
 		seq_printf(seq, "present:                 no\n");
 		goto end;
 	}
 
-	if (battery->info.capacity_mode) {
-		cscale = battery->info.vscale * battery->info.ipscale;
+	if (bat->info.capacity_mode) {
+		cscale = bat->info.vscale * bat->info.ipscale;
 	} else {
-		cscale = battery->info.ipscale;
+		cscale = bat->info.ipscale;
 	}
 
 	seq_printf(seq, "alarm:                   ");
-	if (battery->alarm.remaining_capacity) {
-		seq_printf(seq, "%i%s",
-			   battery->alarm.remaining_capacity * cscale,
-			   battery->info.capacity_mode ? "0 mWh\n" : " mAh\n");
+	if (bat->alarm.remaining_capacity) {
+		seq_printf(seq, "%i%s\n",
+			   bat->alarm.remaining_capacity * cscale,
+			   bat->info.capacity_mode ? "0 mWh" : " mAh");
 	} else {
 		seq_printf(seq, "disabled\n");
 	}
 
       end:
 
-	up(&sbs_sem);
+	sbs_mutex_unlock(sbs);
 
 	return result;
 }
 
 static ssize_t
-acpi_battery_write_alarm(struct file *file, const char __user * buffer,
-			 size_t count, loff_t * ppos)
+acpi_bat_write_alarm(struct file *file, const char __user * buffer,
+		     size_t count, loff_t * ppos)
 {
-	struct seq_file *seq = (struct seq_file *)file->private_data;
-	struct acpi_battery *battery = (struct acpi_battery *)seq->private;
+	struct seq_file *seq = file->private_data;
+	struct acpi_bat *bat = seq->private;
+	struct acpi_sbs *sbs = bat->sbs;
 	char alarm_string[12] = { '\0' };
 	int result, old_alarm, new_alarm;
 
-	if (battery->sbs->zombie) {
+	if (sbs_mutex_lock(sbs)) {
 		return -ENODEV;
 	}
 
-	down(&sbs_sem);
-
-	if (!acpi_battery_is_present(battery)) {
+	if (!bat->bat_present) {
 		result = -ENODEV;
 		goto end;
 	}
@@ -1153,26 +1201,26 @@ acpi_battery_write_alarm(struct file *fi
 
 	alarm_string[count] = 0;
 
-	old_alarm = battery->alarm.remaining_capacity;
+	old_alarm = bat->alarm.remaining_capacity;
 	new_alarm = simple_strtoul(alarm_string, NULL, 0);
 
-	result = acpi_battery_set_alarm(battery, new_alarm);
+	result = acpi_bat_set_alarm(bat, new_alarm);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_battery_set_alarm() failed\n"));
-		(void)acpi_battery_set_alarm(battery, old_alarm);
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_bat_set_alarm() failed\n"));
+		acpi_bat_set_alarm(bat, old_alarm);
 		goto end;
 	}
-	result = acpi_battery_get_alarm(battery);
+	result = acpi_bat_get_alarm(bat);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_battery_get_alarm() failed\n"));
-		(void)acpi_battery_set_alarm(battery, old_alarm);
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_bat_get_alarm() failed\n"));
+		acpi_bat_set_alarm(bat, old_alarm);
 		goto end;
 	}
 
       end:
-	up(&sbs_sem);
+	sbs_mutex_unlock(sbs);
 
 	if (result) {
 		return result;
@@ -1181,31 +1229,31 @@ acpi_battery_write_alarm(struct file *fi
 	}
 }
 
-static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
+static int acpi_bat_alarm_open_fs(struct inode *inode, struct file *file)
 {
-	return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
+	return single_open(file, acpi_bat_read_alarm, PDE(inode)->data);
 }
 
-static struct file_operations acpi_battery_info_fops = {
-	.open = acpi_battery_info_open_fs,
+static struct file_operations acpi_bat_info_fops = {
+	.open = acpi_bat_info_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
 	.release = single_release,
 	.owner = THIS_MODULE,
 };
 
-static struct file_operations acpi_battery_state_fops = {
-	.open = acpi_battery_state_open_fs,
+static struct file_operations acpi_bat_state_fops = {
+	.open = acpi_bat_state_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
 	.release = single_release,
 	.owner = THIS_MODULE,
 };
 
-static struct file_operations acpi_battery_alarm_fops = {
-	.open = acpi_battery_alarm_open_fs,
+static struct file_operations acpi_bat_alarm_fops = {
+	.open = acpi_bat_alarm_open_fs,
 	.read = seq_read,
-	.write = acpi_battery_write_alarm,
+	.write = acpi_bat_write_alarm,
 	.llseek = seq_lseek,
 	.release = single_release,
 	.owner = THIS_MODULE,
@@ -1217,27 +1265,38 @@ static struct proc_dir_entry *acpi_ac_di
 
 static int acpi_ac_read_state(struct seq_file *seq, void *offset)
 {
-	struct acpi_sbs *sbs = (struct acpi_sbs *)seq->private;
+	struct acpi_sbs *sbs = seq->private;
 	int result;
+	unsigned long seconds;
+	int call_update = 0;
 
-	if (sbs->zombie) {
+	if (sbs_mutex_lock(sbs)) {
 		return -ENODEV;
 	}
 
-	down(&sbs_sem);
-
 	if (update_mode == REQUEST_UPDATE_MODE) {
+		call_update = 1;
+	} else if (update_mode == REQUEST_TIME_UPDATE_MODE) {
+		seconds = get_seconds();
+		if (seconds - sbs->ac.seconds >=
+		    update_time * update_time_ac_cnt) {
+			sbs->ac.seconds = seconds;
+			call_update = 1;
+		}
+	}
+
+	if (call_update) {
 		result = acpi_sbs_update_run(sbs, DATA_TYPE_AC_STATE);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_update_run() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbs_update_run() failed\n"));
 		}
 	}
 
 	seq_printf(seq, "state:                   %s\n",
-		   sbs->ac_present ? "on-line" : "off-line");
+		   sbs->ac.ac_present ? "on-line" : "off-line");
 
-	up(&sbs_sem);
+	sbs_mutex_unlock(sbs);
 
 	return 0;
 }
@@ -1261,72 +1320,76 @@ static struct file_operations acpi_ac_st
 
 /* Smart Battery */
 
-static int acpi_battery_add(struct acpi_sbs *sbs, int id)
+static int acpi_bat_add(struct acpi_sbs *sbs, int id)
 {
 	int is_present;
 	int result;
 	char dir_name[32];
-	struct acpi_battery *battery;
+	struct acpi_bat *bat;
 
-	battery = &sbs->battery[id];
+	bat = &sbs->bat[id];
 
-	battery->alive = 0;
+	bat->alive = 0;
 
-	battery->init_state = 0;
-	battery->id = id;
-	battery->sbs = sbs;
+	bat->init_state = 0;
+	bat->id = id;
+	bat->sbs = sbs;
 
-	result = acpi_battery_select(battery);
+	result = acpi_bat_select(bat);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_battery_select() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_bat_select() failed\n"));
 		goto end;
 	}
 
-	result = acpi_battery_get_present(battery);
+	result = acpi_bat_get_present(bat);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_battery_get_present() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_bat_get_present() failed\n"));
 		goto end;
 	}
 
-	is_present = acpi_battery_is_present(battery);
+	is_present = bat->bat_present;
 
 	if (is_present) {
-		result = acpi_battery_init(battery);
+		result = acpi_bat_init(bat);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_battery_init() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_bat_init() failed\n"));
 			goto end;
 		}
-		battery->init_state = 1;
+		bat->init_state = 1;
 	}
 
-	(void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
+	(void)sprintf(dir_name, ACPI_BAT_DIR_NAME, id);
 
-	result = acpi_sbs_generic_add_fs(&battery->battery_entry,
-					 acpi_battery_dir,
+	result = acpi_sbs_generic_add_fs(&bat->bat_entry,
+					 acpi_bat_dir,
 					 dir_name,
-					 &acpi_battery_info_fops,
-					 &acpi_battery_state_fops,
-					 &acpi_battery_alarm_fops, battery);
+					 &acpi_bat_info_fops,
+					 &acpi_bat_state_fops,
+					 &acpi_bat_alarm_fops, bat);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_generic_add_fs() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_generic_add_fs() failed\n"));
 		goto end;
 	}
-	battery->alive = 1;
+	bat->alive = 1;
+
+	printk(KERN_INFO PREFIX "%s [%s] (%s %s)\n",
+	       acpi_device_name(sbs->device), acpi_device_bid(sbs->device),
+	       dir_name, sbs->bat->bat_present ? "present" : "absent");
 
       end:
 	return result;
 }
 
-static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
+static void acpi_bat_remove(struct acpi_sbs *sbs, int id)
 {
 
-	if (sbs->battery[id].battery_entry) {
-		acpi_sbs_generic_remove_fs(&(sbs->battery[id].battery_entry),
-					   acpi_battery_dir);
+	if (sbs->bat[id].bat_entry) {
+		acpi_sbs_generic_remove_fs(&(sbs->bat[id].bat_entry),
+					   acpi_bat_dir);
 	}
 }
 
@@ -1336,8 +1399,8 @@ static int acpi_ac_add(struct acpi_sbs *
 
 	result = acpi_ac_get_present(sbs);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_ac_get_present() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_ac_get_present() failed\n"));
 		goto end;
 	}
 
@@ -1346,10 +1409,15 @@ static int acpi_ac_add(struct acpi_sbs *
 					 ACPI_AC_DIR_NAME,
 					 NULL, &acpi_ac_state_fops, NULL, sbs);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_generic_add_fs() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_generic_add_fs() failed\n"));
 		goto end;
 	}
+	sbs->ac.seconds = get_seconds();
+
+	printk(KERN_INFO PREFIX "%s [%s] (%s %s)\n",
+	       acpi_device_name(sbs->device), acpi_device_bid(sbs->device),
+	       ACPI_AC_DIR_NAME, sbs->ac.ac_present ? "on-line" : "off-line");
 
       end:
 
@@ -1364,224 +1432,249 @@ static void acpi_ac_remove(struct acpi_s
 	}
 }
 
-static void acpi_sbs_update_queue_run(unsigned long data)
+static void acpi_sbs_update_time_run(unsigned long data)
 {
-	acpi_os_execute(OSL_GPE_HANDLER, acpi_sbs_update_queue, (void *)data);
+	acpi_os_execute(OSL_GPE_HANDLER, acpi_sbs_update_time, (void *)data);
 }
 
 static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
 {
-	struct acpi_battery *battery;
+	struct acpi_bat *bat;
 	int result = 0;
-	int old_ac_present;
-	int old_battery_present;
-	int new_ac_present;
-	int new_battery_present;
+	int old_ac_present = -1;
+	int old_bat_present = -1;
+	int new_ac_present = -1;
+	int new_bat_present = -1;
 	int id;
 	char dir_name[32];
-	int do_battery_init, do_ac_init;
-	s16 old_remaining_capacity;
+	int do_bat_init = 0, do_ac_init = 0;
+	int old_remaining_capacity = 0;
+	int update_ac = 1, update_bat = 1;
 
-	if (sbs->zombie) {
+	if (sbs_zombie(sbs)) {
+		goto end;
+	}
+
+	if (data_type == DATA_TYPE_COMMON) {
+		if (sbs->run_cnt % update_time_ac_cnt != 0) {
+			update_ac = 0;
+		}
+		if (sbs->run_cnt % update_time_bat_cnt != 0) {
+			update_bat = 0;
+		}
+	}
+
+	sbs->run_cnt++;
+
+	if (update_ac == 0 && update_bat == 0) {
 		goto end;
 	}
 
-	old_ac_present = acpi_ac_is_present(sbs);
+	old_ac_present = sbs->ac.ac_present;
 
 	result = acpi_ac_get_present(sbs);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_ac_get_present() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_ac_get_present() failed\n"));
 	}
 
-	new_ac_present = acpi_ac_is_present(sbs);
+	new_ac_present = sbs->ac.ac_present;
 
 	do_ac_init = (old_ac_present != new_ac_present);
+	if (sbs->run_cnt == 1) {
+		do_ac_init = 1;
+	}
 
-	if (data_type == DATA_TYPE_AC_STATE) {
+	if (do_ac_init) {
+		result = acpi_sbs_generate_event(sbs->device,
+						 ACPI_SBS_AC_NOTIFY_STATUS,
+						 new_ac_present,
+						 ACPI_AC_DIR_NAME,
+						 ACPI_AC_CLASS);
+		if (result) {
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbs_generate_event() failed\n"));
+		}
+	}
+
+	if (data_type == DATA_TYPE_COMMON) {
+		if (!do_ac_init && update_bat == 0) {
+			goto end;
+		}
+	}
+
+	if (data_type == DATA_TYPE_AC_STATE && !do_ac_init) {
 		goto end;
 	}
 
 	for (id = 0; id < MAX_SBS_BAT; id++) {
-		battery = &sbs->battery[id];
-		if (battery->alive == 0) {
+		bat = &sbs->bat[id];
+		if (bat->alive == 0) {
 			continue;
 		}
 
-		old_remaining_capacity = battery->state.remaining_capacity;
+		old_remaining_capacity = bat->state.remaining_capacity;
 
-		old_battery_present = acpi_battery_is_present(battery);
+		old_bat_present = bat->bat_present;
 
-		result = acpi_battery_select(battery);
+		result = acpi_bat_select(bat);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_battery_select() failed\n"));
-		}
-		if (sbs->zombie) {
-			goto end;
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_bat_select() failed\n"));
 		}
 
-		result = acpi_battery_get_present(battery);
+		result = acpi_bat_get_present(bat);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_battery_get_present() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_bat_get_present() failed\n"));
 		}
-		if (sbs->zombie) {
-			goto end;
-		}
-
-		new_battery_present = acpi_battery_is_present(battery);
 
-		do_battery_init = ((old_battery_present != new_battery_present)
-				   && new_battery_present);
+		new_bat_present = bat->bat_present;
 
-		if (sbs->zombie) {
+		do_bat_init = ((old_bat_present != new_bat_present)
+			       && new_bat_present);
+		if (!new_bat_present)
+			goto event;
+		if (do_ac_init || do_bat_init) {
+			result = acpi_bat_init(bat);
+			if (result) {
+				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+						"acpi_bat_init() " "failed\n"));
+			}
+		}
+		if (sbs_zombie(sbs)) {
 			goto end;
 		}
-		if (do_ac_init || do_battery_init ||
-		    update_info_mode || sbs->update_info_mode) {
-			if (sbs->update_info_mode) {
-				sbs->update_info_mode = 0;
-			} else {
-				sbs->update_info_mode = 1;
-			}
-			result = acpi_battery_init(battery);
+
+		if ((data_type == DATA_TYPE_COMMON
+		     || data_type == DATA_TYPE_BAT_INFO)
+		    && new_bat_present
+		    && update_bat_info_mode == UPDATE_BAT_INFO_MODE) {
+			result = acpi_bat_get_info(bat);
 			if (result) {
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "acpi_battery_init() "
-						  "failed\n"));
+				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+						"acpi_bat_get_info() "
+						"failed\n"));
 			}
 		}
-		if (data_type == DATA_TYPE_INFO) {
+		if (data_type == DATA_TYPE_BAT_INFO) {
 			continue;
 		}
-
-		if (sbs->zombie) {
+		if (sbs_zombie(sbs)) {
 			goto end;
 		}
-		if (new_battery_present) {
-			result = acpi_battery_get_alarm(battery);
-			if (result) {
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "acpi_battery_get_alarm() "
-						  "failed\n"));
-			}
-			if (data_type == DATA_TYPE_ALARM) {
-				continue;
-			}
 
-			result = acpi_battery_get_state(battery);
+		if ((data_type == DATA_TYPE_COMMON
+		     || data_type == DATA_TYPE_BAT_STATE)
+		    && new_bat_present) {
+			result = acpi_bat_get_state(bat);
 			if (result) {
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "acpi_battery_get_state() "
-						  "failed\n"));
+				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+						"acpi_bat_get_state() "
+						"failed\n"));
 			}
 		}
-		if (sbs->zombie) {
-			goto end;
+		if (data_type == DATA_TYPE_BAT_STATE) {
+			goto event;
 		}
-		if (data_type != DATA_TYPE_COMMON) {
-			continue;
+		if (sbs_zombie(sbs)) {
+			goto end;
 		}
 
-		if (old_battery_present != new_battery_present) {
-			(void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
-			result = acpi_sbs_generate_event(sbs->device,
-							 ACPI_SBS_BATTERY_NOTIFY_STATUS,
-							 new_battery_present,
-							 dir_name,
-							 ACPI_BATTERY_CLASS);
+		if ((data_type == DATA_TYPE_COMMON
+		     || data_type == DATA_TYPE_BAT_ALARM)
+		    && new_bat_present) {
+			result = acpi_bat_get_alarm(bat);
 			if (result) {
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "acpi_sbs_generate_event() "
-						  "failed\n"));
+				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+						"acpi_bat_get_alarm() "
+						"failed\n"));
 			}
 		}
-		if (old_remaining_capacity != battery->state.remaining_capacity) {
-			(void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
+		if (data_type == DATA_TYPE_BAT_ALARM) {
+			continue;
+		}
+		if (sbs_zombie(sbs)) {
+			goto end;
+		}
+
+	      event:
+
+		if (old_bat_present != new_bat_present ||
+		    old_remaining_capacity != bat->state.remaining_capacity) {
+			(void)sprintf(dir_name, ACPI_BAT_DIR_NAME, id);
 			result = acpi_sbs_generate_event(sbs->device,
-							 ACPI_SBS_BATTERY_NOTIFY_STATUS,
-							 new_battery_present,
+							 ACPI_SBS_BAT_NOTIFY_STATUS,
+							 new_bat_present,
 							 dir_name,
-							 ACPI_BATTERY_CLASS);
+							 ACPI_BAT_CLASS);
 			if (result) {
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "acpi_sbs_generate_event() failed\n"));
+				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+						"acpi_sbs_generate_event() "
+						"failed\n"));
 			}
 		}
-
-	}
-	if (sbs->zombie) {
-		goto end;
-	}
-	if (data_type != DATA_TYPE_COMMON) {
-		goto end;
-	}
-
-	if (old_ac_present != new_ac_present) {
-		result = acpi_sbs_generate_event(sbs->device,
-						 ACPI_SBS_AC_NOTIFY_STATUS,
-						 new_ac_present,
-						 ACPI_AC_DIR_NAME,
-						 ACPI_AC_CLASS);
-		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_generate_event() failed\n"));
-		}
 	}
 
       end:
+
 	return result;
 }
 
-static void acpi_sbs_update_queue(void *data)
+static void acpi_sbs_update_time(void *data)
 {
 	struct acpi_sbs *sbs = data;
 	unsigned long delay = -1;
 	int result;
 
-	if (sbs->zombie) {
-		goto end;
-	}
+	if (sbs_mutex_lock(sbs))
+		return;
 
 	result = acpi_sbs_update_run(sbs, DATA_TYPE_COMMON);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_update_run() failed\n"));
-	}
-
-	if (sbs->zombie) {
-		goto end;
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_update_run() failed\n"));
 	}
 
-	if (update_mode == REQUEST_UPDATE_MODE) {
+	if (sbs_zombie(sbs)) {
 		goto end;
 	}
 
 	delay = jiffies + HZ * update_time;
 	sbs->update_timer.data = (unsigned long)data;
-	sbs->update_timer.function = acpi_sbs_update_queue_run;
+	sbs->update_timer.function = acpi_sbs_update_time_run;
 	sbs->update_timer.expires = delay;
 	add_timer(&sbs->update_timer);
+
       end:
+
+	sbs_mutex_unlock(sbs);
+
 	;
 }
 
+#define STRUCT_TO_INT(s)	(*((int*)&s))
+
 static int acpi_sbs_add(struct acpi_device *device)
 {
 	struct acpi_sbs *sbs = NULL;
 	struct acpi_ec_hc *ec_hc = NULL;
-	int result, remove_result = 0;
+	int result = 0, remove_result = 0;
 	unsigned long sbs_obj;
 	int id, cnt;
 	acpi_status status = AE_OK;
 
 	sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL);
 	if (!sbs) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "kmalloc() failed\n"));
-		return -ENOMEM;
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "kzalloc() failed\n"));
+		result = -ENOMEM;
+		goto end;
 	}
 
+	mutex_init(&sbs->mutex);
+
+	sbs_mutex_lock(sbs);
+
 	cnt = 0;
 	while (cnt < 10) {
 		cnt++;
@@ -1593,9 +1686,9 @@ static int acpi_sbs_add(struct acpi_devi
 	}
 
 	if (!ec_hc) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_get_ec_hc() failed: "
-				  "NO driver found for EC HC SMBus\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_get_ec_hc() failed: "
+				"NO driver found for EC HC SMBus\n"));
 		result = -ENODEV;
 		goto end;
 	}
@@ -1608,17 +1701,17 @@ static int acpi_sbs_add(struct acpi_devi
 	acpi_driver_data(device) = sbs;
 
 	sbs->update_time = 0;
-	sbs->update_time2 = 0;
+	sbs->update_time_io_delay = 0;
 
 	result = acpi_ac_add(sbs);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "acpi_ac_add() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed\n"));
 		goto end;
 	}
 	result = acpi_evaluate_integer(device->handle, "_SBS", NULL, &sbs_obj);
 	if (ACPI_FAILURE(result)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_evaluate_integer() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_evaluate_integer() failed\n"));
 		result = -EIO;
 		goto end;
 	}
@@ -1626,27 +1719,27 @@ static int acpi_sbs_add(struct acpi_devi
 	if (sbs_obj > 0) {
 		result = acpi_sbsm_get_info(sbs);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbsm_get_info() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbsm_get_info() failed\n"));
 			goto end;
 		}
 		sbs->sbsm_present = 1;
 	}
 	if (sbs->sbsm_present == 0) {
-		result = acpi_battery_add(sbs, 0);
+		result = acpi_bat_add(sbs, 0);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_battery_add() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_bat_add() failed\n"));
 			goto end;
 		}
 	} else {
 		for (id = 0; id < MAX_SBS_BAT; id++) {
 			if ((sbs->sbsm_batteries_supported & (1 << id))) {
-				result = acpi_battery_add(sbs, id);
+				result = acpi_bat_add(sbs, id);
 				if (result) {
-					ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-							  "acpi_battery_add() "
-							  "failed\n"));
+					ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+							"acpi_bat_add() "
+							"failed\n"));
 					goto end;
 				}
 			}
@@ -1656,65 +1749,151 @@ static int acpi_sbs_add(struct acpi_devi
 	sbs->handle = device->handle;
 
 	init_timer(&sbs->update_timer);
-	if (update_mode == QUEUE_UPDATE_MODE) {
+	if (update_mode == TIME_UPDATE_MODE) {
 		status = acpi_os_execute(OSL_GPE_HANDLER,
-					 acpi_sbs_update_queue, (void *)sbs);
+					 acpi_sbs_update_time, sbs);
 		if (status != AE_OK) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_os_execute() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_os_execute() failed\n"));
 		}
 	}
 	sbs->update_time = update_time;
-	sbs->update_time2 = update_time2;
+	sbs->update_time_io_delay = update_time_io_delay;
 
-	printk(KERN_INFO PREFIX "%s [%s]\n",
-	       acpi_device_name(device), acpi_device_bid(device));
+	status = acpi_install_notify_handler(device->handle,
+					     ACPI_ALL_NOTIFY, acpi_sbs_notify,
+					     sbs);
+	if (ACPI_FAILURE(status)) {
+		result = -ENODEV;
+		goto end;
+	}
 
       end:
+
+	sbs_mutex_unlock(sbs);
+
 	if (result) {
 		remove_result = acpi_sbs_remove(device, 0);
 		if (remove_result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_remove() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbs_remove() failed\n"));
 		}
 	}
 
 	return result;
 }
 
-int acpi_sbs_remove(struct acpi_device *device, int type)
+static void acpi_sbs_notify(acpi_handle handle, u32 event, void *data)
 {
-	struct acpi_sbs *sbs = NULL;
+	struct acpi_sbs *sbs;
+	struct acpi_device *device = NULL;
+	int result;
+
+	if (!data)
+		return;
+
+	sbs = data;
+
+	if (!sbs)
+		return;
+
+	device = sbs->device;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "acpi_sbs_notify: event %d\n",
+			  (int)event));
+
+	result = acpi_bus_get_status(device);
+	if (result) {
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_bus_get_status() failed\n"));
+	}
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			  "status %d\n", STRUCT_TO_INT(device->status)));
+
+	acpi_bus_generate_event(device, event, device->status.present);
+}
+
+static int acpi_sbs_suspend(struct acpi_device *device, int state)
+{
+	struct acpi_sbs *sbs;
+
+	if (!device)
+		return -EINVAL;
+
+	sbs = acpi_driver_data(device);
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "acpi_sbs_suspend: state %d\n", state));
+
+	return 0;
+}
+
+static int acpi_sbs_resume(struct acpi_device *device, int state)
+{
+	struct acpi_sbs *sbs;
+
+	if (!device)
+		return -EINVAL;
+
+	sbs = acpi_driver_data(device);
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "acpi_sbs_resume: state %d\n", state));
+
+	return 0;
+}
+
+static int acpi_sbs_remove(struct acpi_device *device, int type)
+{
+	struct acpi_sbs *sbs;
 	int id;
 
 	if (!device) {
 		return -EINVAL;
 	}
 
-	sbs = (struct acpi_sbs *)acpi_driver_data(device);
-
+	sbs = acpi_driver_data(device);
 	if (!sbs) {
 		return -EINVAL;
 	}
 
+	sbs_mutex_lock(sbs);
+
+	(void)acpi_remove_notify_handler(device->handle,
+					 ACPI_ALL_NOTIFY, acpi_sbs_notify);
+
 	sbs->zombie = 1;
 	sbs->update_time = 0;
-	sbs->update_time2 = 0;
+	sbs->update_time_io_delay = 0;
 	del_timer_sync(&sbs->update_timer);
 	acpi_os_wait_events_complete(NULL);
 	del_timer_sync(&sbs->update_timer);
 
 	for (id = 0; id < MAX_SBS_BAT; id++) {
-		acpi_battery_remove(sbs, id);
+		acpi_bat_remove(sbs, id);
 	}
 
 	acpi_ac_remove(sbs);
 
+	sbs_mutex_unlock(sbs);
+
+	mutex_destroy(&sbs->mutex);
+
 	kfree(sbs);
 
 	return 0;
 }
 
+static void acpi_sbs_rmdirs(void)
+{
+	if (acpi_ac_dir) {
+		acpi_unlock_ac_dir(acpi_ac_dir);
+		acpi_ac_dir = NULL;
+	}
+	if (acpi_bat_dir) {
+		acpi_unlock_battery_dir(acpi_bat_dir);
+		acpi_bat_dir = NULL;
+	}
+}
+
 static int __init acpi_sbs_init(void)
 {
 	int result = 0;
@@ -1722,35 +1901,77 @@ static int __init acpi_sbs_init(void)
 	if (acpi_disabled)
 		return -ENODEV;
 
-	init_MUTEX(&sbs_sem);
-
 	if (capacity_mode != DEF_CAPACITY_UNIT
 	    && capacity_mode != MAH_CAPACITY_UNIT
 	    && capacity_mode != MWH_CAPACITY_UNIT) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "acpi_sbs_init: "
-				  "invalid capacity_mode = %d\n",
-				  capacity_mode));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"invalid capacity_mode = %d\n", capacity_mode));
+		return -EINVAL;
+	}
+
+	if (update_mode != REQUEST_UPDATE_MODE
+	    && update_mode != REQUEST_TIME_UPDATE_MODE
+	    && update_mode != TIME_UPDATE_MODE) {
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"invalid update_mode = %d\n", update_mode));
+		return -EINVAL;
+	}
+
+	if (update_bat_info_mode != UPDATE_BAT_INFO_MODE
+	    && update_bat_info_mode != NON_UPDATE_INFO_MODE) {
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"invalid update_bat_info_mode = %d\n",
+				update_bat_info_mode));
+		return -EINVAL;
+	}
+
+	if (update_time < 0) {
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"invalid update_time_ac = %d\n", update_time));
+		return -EINVAL;
+	}
+
+	if (update_time_ac_cnt <= 0) {
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"invalid update_time_ac = %d\n",
+				update_time_ac_cnt));
+		return -EINVAL;
+	}
+
+	if (update_time_bat_cnt <= 0) {
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"invalid update_time_bat = %d\n",
+				update_time_bat_cnt));
+		return -EINVAL;
+	}
+
+	if (update_time_io_delay < 0) {
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"invalid update_time_io_delay = %d\n",
+				update_time_io_delay));
 		return -EINVAL;
 	}
 
 	acpi_ac_dir = acpi_lock_ac_dir();
 	if (!acpi_ac_dir) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_lock_ac_dir() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_lock_ac_dir() failed\n"));
 		return -ENODEV;
 	}
 
-	acpi_battery_dir = acpi_lock_battery_dir();
-	if (!acpi_battery_dir) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_lock_battery_dir() failed\n"));
+	acpi_bat_dir = acpi_lock_battery_dir();
+	if (!acpi_bat_dir) {
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_lock_battery_dir() failed\n"));
+		acpi_sbs_rmdirs();
 		return -ENODEV;
 	}
 
 	result = acpi_bus_register_driver(&acpi_sbs_driver);
 	if (result < 0) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_bus_register_driver() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_bus_register_driver() failed\n"));
+		acpi_sbs_rmdirs();
 		return -ENODEV;
 	}
 
@@ -1759,13 +1980,9 @@ static int __init acpi_sbs_init(void)
 
 static void __exit acpi_sbs_exit(void)
 {
-
 	acpi_bus_unregister_driver(&acpi_sbs_driver);
 
-	acpi_unlock_ac_dir(acpi_ac_dir);
-	acpi_ac_dir = NULL;
-	acpi_unlock_battery_dir(acpi_battery_dir);
-	acpi_battery_dir = NULL;
+	acpi_sbs_rmdirs();
 
 	return;
 }

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2007-01-26  9:11 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-11-28  2:25 sbs driver Lebedev, Vladimir P
2007-01-26  9:10 ` Len Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).