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

* Re: sbs driver
  2006-11-28  2:25 sbs driver Lebedev, Vladimir P
@ 2007-01-26  9:10 ` Len Brown
  0 siblings, 0 replies; 2+ messages in thread
From: Len Brown @ 2007-01-26  9:10 UTC (permalink / raw)
  To: Lebedev, Vladimir P; +Cc: Starikovskiy, Alexey Y, linux-acpi

On Monday 27 November 2006 21:25, Lebedev, Vladimir P wrote:
> 
> 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,
Looks like we failed to merge this one.
(in general, if I don't ack or somehow respond within a week or so, re-ping.
 This one was sent the day after Thanksgiving here in the US
 and I never saw it)

Is this patch entirely clean-up, or are there any functional changes?

Sifting through the 1500 line patch it was hard to tell, but it
looked to be at least mostly cleanup, with maybe some
of the errors messages changed.

Please refresh this patch against 2.6.20-rc6
If there are any functional changes, please split them out
into a single patch per logical change and send a series
and provide check in comments describing exactly
what changed and why.

thanks,
-Len


^ 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).