All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 12/12] ACPI: SBS: Add ACPI_PROCFS around procfs handling code.
  2007-08-16 14:03 [PATCH 01/12] ACPI: AC: Add sysfs interface Alexey Starikovskiy
@ 2007-08-16 14:04 ` Alexey Starikovskiy
  0 siblings, 0 replies; 14+ messages in thread
From: Alexey Starikovskiy @ 2007-08-16 14:04 UTC (permalink / raw)
  To: lenb, linux-acpi; +Cc: astarikovskiy

Make procfs support optional under ACPI_PROCFS

Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
---

 drivers/acpi/sbs.c |   21 +++++++++++++++++++++
 1 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 87bee1e..7db85a9 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -29,9 +29,11 @@
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
 
+#ifdef CONFIG_ACPI_PROCFS
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <asm/uaccess.h>
+#endif
 
 #include <linux/acpi.h>
 #include <linux/timer.h>
@@ -91,7 +93,9 @@ struct acpi_battery {
 	struct power_supply bat;
 #endif
 	struct acpi_sbs *sbs;
+#ifdef CONFIG_ACPI_PROCFS
 	struct proc_dir_entry *proc_entry;
+#endif
 	unsigned long update_time;
 	char name[8];
 	char manufacturer_name[ACPI_SBS_BLOCK_MAX];
@@ -125,7 +129,9 @@ struct acpi_sbs {
 	struct acpi_device *device;
 	struct acpi_smb_hc *hc;
 	struct mutex lock;
+#ifdef CONFIG_ACPI_PROCFS
 	struct proc_dir_entry *charger_entry;
+#endif
 	struct acpi_battery battery[MAX_SBS_BAT];
 	u8 batteries_supported:4;
 	u8 manager_present:1;
@@ -389,6 +395,8 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 	return result;
 }
 
+#ifdef CONFIG_ACPI_PROCFS
+
 static int acpi_battery_get_alarm(struct acpi_battery *battery)
 {
 	return acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
@@ -424,6 +432,7 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery)
       end:
 	return ret;
 }
+#endif
 
 static int acpi_ac_get_present(struct acpi_sbs *sbs)
 {
@@ -759,10 +768,12 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
 		return result;
 
 	sprintf(battery->name, ACPI_BATTERY_DIR_NAME, id);
+#ifdef CONFIG_ACPI_PROCFS
 	acpi_sbs_add_fs(&battery->proc_entry, acpi_battery_dir,
 			battery->name, &acpi_battery_info_fops,
 			&acpi_battery_state_fops, &acpi_battery_alarm_fops,
 			battery);
+#endif
 #ifdef ENABLE_POWER_SUPPLY
 	battery->bat.name = battery->name;
 	battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
@@ -790,10 +801,12 @@ static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
 	if (sbs->battery[id].bat.dev)
 		power_supply_unregister(&sbs->battery[id].bat);
 #endif
+#ifdef CONFIG_ACPI_PROCFS
 	if (sbs->battery[id].proc_entry) {
 		acpi_sbs_remove_fs(&(sbs->battery[id].proc_entry),
 				   acpi_battery_dir);
 	}
+#endif
 }
 
 static int acpi_charger_add(struct acpi_sbs *sbs)
@@ -803,11 +816,13 @@ static int acpi_charger_add(struct acpi_sbs *sbs)
 	result = acpi_ac_get_present(sbs);
 	if (result)
 		goto end;
+#ifdef CONFIG_ACPI_PROCFS
 	result = acpi_sbs_add_fs(&sbs->charger_entry, acpi_ac_dir,
 				 ACPI_AC_DIR_NAME, NULL,
 				 &acpi_ac_state_fops, NULL, sbs);
 	if (result)
 		goto end;
+#endif
 #ifdef ENABLE_POWER_SUPPLY
 	sbs->charger.name = "sbs-charger";
 	sbs->charger.type = POWER_SUPPLY_TYPE_MAINS;
@@ -829,8 +844,10 @@ static void acpi_charger_remove(struct acpi_sbs *sbs)
 	if (sbs->charger.dev)
 		power_supply_unregister(&sbs->charger);
 #endif
+#ifdef CONFIG_ACPI_PROCFS
 	if (sbs->charger_entry)
 		acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir);
+#endif
 }
 
 void acpi_sbs_callback(void *context)
@@ -933,6 +950,7 @@ static int acpi_sbs_remove(struct acpi_device *device, int type)
 
 static void acpi_sbs_rmdirs(void)
 {
+#ifdef CONFIG_ACPI_PROCFS
 	if (acpi_ac_dir) {
 		acpi_unlock_ac_dir(acpi_ac_dir);
 		acpi_ac_dir = NULL;
@@ -941,6 +959,7 @@ static void acpi_sbs_rmdirs(void)
 		acpi_unlock_battery_dir(acpi_battery_dir);
 		acpi_battery_dir = NULL;
 	}
+#endif
 }
 
 static int acpi_sbs_resume(struct acpi_device *device)
@@ -970,6 +989,7 @@ static int __init acpi_sbs_init(void)
 
 	if (acpi_disabled)
 		return -ENODEV;
+#ifdef CONFIG_ACPI_PROCFS
 	acpi_ac_dir = acpi_lock_ac_dir();
 	if (!acpi_ac_dir)
 		return -ENODEV;
@@ -978,6 +998,7 @@ static int __init acpi_sbs_init(void)
 		acpi_sbs_rmdirs();
 		return -ENODEV;
 	}
+#endif
 	result = acpi_bus_register_driver(&acpi_sbs_driver);
 	if (result < 0) {
 		acpi_sbs_rmdirs();


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

* [PATCH 01/12] ACPI: AC: Add sysfs interface
@ 2007-08-16 14:25 Alexey Starikovskiy
  2007-08-16 14:26 ` [PATCH 02/12] ACPI: Battery: don't use acpi_extract_package() Alexey Starikovskiy
                   ` (10 more replies)
  0 siblings, 11 replies; 14+ messages in thread
From: Alexey Starikovskiy @ 2007-08-16 14:25 UTC (permalink / raw)
  To: lenb, linux-acpi; +Cc: astarikovskiy

Refer to Documentation/power_supply_class.txt for interface description.

Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
---

 drivers/acpi/ac.c |   49 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index d8b3509..d13b961 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -29,6 +29,12 @@
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+
+#if defined(CONFIG_POWER_SUPPLY) || defined(CONFIG_POWER_SUPPLY_MODULE)
+#define ENABLE_POWER_SUPPLY
+#include <linux/power_supply.h>
+#endif
+
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
@@ -72,16 +78,42 @@ static struct acpi_driver acpi_ac_driver = {
 };
 
 struct acpi_ac {
+#ifdef ENABLE_POWER_SUPPLY
+	struct power_supply charger;
+#endif
 	struct acpi_device * device;
 	unsigned long state;
 };
 
+#define to_acpi_ac(x) container_of(x, struct acpi_ac, charger);
+
 static const struct file_operations acpi_ac_fops = {
 	.open = acpi_ac_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
 	.release = single_release,
 };
+#ifdef ENABLE_POWER_SUPPLY
+static int get_ac_property(struct power_supply *psy,
+			   enum power_supply_property psp,
+			   union power_supply_propval *val)
+{
+	struct acpi_ac *ac = to_acpi_ac(psy);
+	switch (psp) {
+	case POWER_SUPPLY_PROP_ONLINE:
+		val->intval = ac->state;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static enum power_supply_property ac_props[] = {
+	POWER_SUPPLY_PROP_ONLINE,
+};
+
+#endif
 
 /* --------------------------------------------------------------------------
                                AC Adapter Management
@@ -205,6 +237,9 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
 	case ACPI_NOTIFY_DEVICE_CHECK:
 		acpi_ac_get_state(ac);
 		acpi_bus_generate_event(device, event, (u32) ac->state);
+#ifdef ENABLE_POWER_SUPPLY
+		kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
+#endif
 		break;
 	default:
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -241,7 +276,14 @@ static int acpi_ac_add(struct acpi_device *device)
 	result = acpi_ac_add_fs(device);
 	if (result)
 		goto end;
-
+#ifdef ENABLE_POWER_SUPPLY
+	ac->charger.name = acpi_device_bid(device);
+	ac->charger.type = POWER_SUPPLY_TYPE_MAINS;
+	ac->charger.properties = ac_props;
+	ac->charger.num_properties = ARRAY_SIZE(ac_props);
+	ac->charger.get_property = get_ac_property;
+	power_supply_register(&ac->device->dev, &ac->charger);
+#endif
 	status = acpi_install_notify_handler(device->handle,
 					     ACPI_ALL_NOTIFY, acpi_ac_notify,
 					     ac);
@@ -276,7 +318,10 @@ static int acpi_ac_remove(struct acpi_device *device, int type)
 
 	status = acpi_remove_notify_handler(device->handle,
 					    ACPI_ALL_NOTIFY, acpi_ac_notify);
-
+#ifdef ENABLE_POWER_SUPPLY
+	if (ac->charger.dev)
+		power_supply_unregister(&ac->charger);
+#endif
 	acpi_ac_remove_fs(device);
 
 	kfree(ac);


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

* [PATCH 02/12] ACPI: Battery: don't use acpi_extract_package()
  2007-08-16 14:25 [PATCH 01/12] ACPI: AC: Add sysfs interface Alexey Starikovskiy
@ 2007-08-16 14:26 ` Alexey Starikovskiy
  2007-08-16 14:26 ` [PATCH 03/12] ACPI: Battery: simplify update scheme Alexey Starikovskiy
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Alexey Starikovskiy @ 2007-08-16 14:26 UTC (permalink / raw)
  To: lenb, linux-acpi; +Cc: astarikovskiy

acpi_extract_package() creates more problems with memory management than
solves as helper for package handling.

Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
---

 drivers/acpi/battery.c |  309 +++++++++++++++++++-----------------------------
 1 files changed, 123 insertions(+), 186 deletions(-)

diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index d7b499f..14bdfad 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -36,9 +36,6 @@
 
 #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
 
-#define ACPI_BATTERY_FORMAT_BIF	"NNNNNNNNNSSSS"
-#define ACPI_BATTERY_FORMAT_BST	"NNNN"
-
 #define ACPI_BATTERY_COMPONENT		0x00040000
 #define ACPI_BATTERY_CLASS		"battery"
 #define ACPI_BATTERY_DEVICE_NAME	"Battery"
@@ -90,29 +87,6 @@ static struct acpi_driver acpi_battery_driver = {
 		},
 };
 
-struct acpi_battery_state {
-	acpi_integer state;
-	acpi_integer present_rate;
-	acpi_integer remaining_capacity;
-	acpi_integer present_voltage;
-};
-
-struct acpi_battery_info {
-	acpi_integer power_unit;
-	acpi_integer design_capacity;
-	acpi_integer last_full_capacity;
-	acpi_integer battery_technology;
-	acpi_integer design_voltage;
-	acpi_integer design_capacity_warning;
-	acpi_integer design_capacity_low;
-	acpi_integer battery_capacity_granularity_1;
-	acpi_integer battery_capacity_granularity_2;
-	acpi_string model_number;
-	acpi_string serial_number;
-	acpi_string battery_type;
-	acpi_string oem_info;
-};
-
 enum acpi_battery_files {
 	ACPI_BATTERY_INFO = 0,
 	ACPI_BATTERY_STATE,
@@ -120,32 +94,42 @@ enum acpi_battery_files {
 	ACPI_BATTERY_NUMFILES,
 };
 
-struct acpi_battery_flags {
-	u8 battery_present_prev;
-	u8 alarm_present;
-	u8 init_update;
-	u8 update[ACPI_BATTERY_NUMFILES];
-	u8 power_unit;
-};
-
 struct acpi_battery {
 	struct acpi_device *device;
-	struct acpi_battery_flags flags;
-	struct acpi_buffer bif_data;
-	struct acpi_buffer bst_data;
 	struct mutex lock;
 	unsigned long alarm;
 	unsigned long update_time[ACPI_BATTERY_NUMFILES];
-
+	int state;
+	int present_rate;
+	int remaining_capacity;
+	int present_voltage;
+	int power_unit;
+	int design_capacity;
+	int last_full_capacity;
+	int technology;
+	int design_voltage;
+	int design_capacity_warning;
+	int design_capacity_low;
+	int capacity_granularity_1;
+	int capacity_granularity_2;
+	char model_number[32];
+	char serial_number[32];
+	char type[32];
+	char oem_info[32];
+	u8 present_prev;
+	u8 alarm_present;
+	u8 init_update;
+	u8 update[ACPI_BATTERY_NUMFILES];
 };
 
 inline int acpi_battery_present(struct acpi_battery *battery)
 {
 	return battery->device->status.battery_present;
 }
+
 inline char *acpi_battery_power_units(struct acpi_battery *battery)
 {
-	if (battery->flags.power_unit)
+	if (battery->power_unit)
 		return ACPI_BATTERY_UNITS_AMPS;
 	else
 		return ACPI_BATTERY_UNITS_WATTS;
@@ -166,43 +150,63 @@ static void acpi_battery_check_result(struct acpi_battery *battery, int result)
 		return;
 
 	if (result) {
-		battery->flags.init_update = 1;
+		battery->init_update = 1;
 	}
 }
 
-static int acpi_battery_extract_package(struct acpi_battery *battery,
-					union acpi_object *package,
-					struct acpi_buffer *format,
-					struct acpi_buffer *data,
-					char *package_name)
-{
-	acpi_status status = AE_OK;
-	struct acpi_buffer data_null = { 0, NULL };
+struct acpi_offsets {
+	size_t offset;		/* offset inside struct acpi_sbs_battery */
+	u8 mode;		/* int or string? */
+};
 
-	status = acpi_extract_package(package, format, &data_null);
-	if (status != AE_BUFFER_OVERFLOW) {
-		ACPI_EXCEPTION((AE_INFO, status, "Extracting size %s",
-				package_name));
-		return -ENODEV;
-	}
+static struct acpi_offsets state_offsets[] = {
+	{offsetof(struct acpi_battery, state), 0},
+	{offsetof(struct acpi_battery, present_rate), 0},
+	{offsetof(struct acpi_battery, remaining_capacity), 0},
+	{offsetof(struct acpi_battery, present_voltage), 0},
+};
 
-	if (data_null.length != data->length) {
-		kfree(data->pointer);
-		data->pointer = kzalloc(data_null.length, GFP_KERNEL);
-		if (!data->pointer) {
-			ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "kzalloc()"));
-			return -ENOMEM;
-		}
-		data->length = data_null.length;
-	}
+static struct acpi_offsets info_offsets[] = {
+	{offsetof(struct acpi_battery, power_unit), 0},
+	{offsetof(struct acpi_battery, design_capacity), 0},
+	{offsetof(struct acpi_battery, last_full_capacity), 0},
+	{offsetof(struct acpi_battery, technology), 0},
+	{offsetof(struct acpi_battery, design_voltage), 0},
+	{offsetof(struct acpi_battery, design_capacity_warning), 0},
+	{offsetof(struct acpi_battery, design_capacity_low), 0},
+	{offsetof(struct acpi_battery, capacity_granularity_1), 0},
+	{offsetof(struct acpi_battery, capacity_granularity_2), 0},
+	{offsetof(struct acpi_battery, model_number), 1},
+	{offsetof(struct acpi_battery, serial_number), 1},
+	{offsetof(struct acpi_battery, type), 1},
+	{offsetof(struct acpi_battery, oem_info), 1},
+};
 
-	status = acpi_extract_package(package, format, data);
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status, "Extracting %s",
-				package_name));
-		return -ENODEV;
+static int extract_package(struct acpi_battery *battery,
+			   union acpi_object *package,
+			   struct acpi_offsets *offsets, int num)
+{
+	int i, *x;
+	union acpi_object *element;
+	if (package->type != ACPI_TYPE_PACKAGE)
+		return -EFAULT;
+	for (i = 0; i < num; ++i) {
+		if (package->package.count <= i)
+			return -EFAULT;
+		element = &package->package.elements[i];
+		if (offsets[i].mode) {
+			if (element->type != ACPI_TYPE_STRING &&
+			    element->type != ACPI_TYPE_BUFFER)
+				return -EFAULT;
+			strncpy((u8 *)battery + offsets[i].offset,
+				element->string.pointer, 32);
+		} else {
+			if (element->type != ACPI_TYPE_INTEGER)
+				return -EFAULT;
+			x = (int *)((u8 *)battery + offsets[i].offset);
+			*x = element->integer.value;
+		}
 	}
-
 	return 0;
 }
 
@@ -223,19 +227,10 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 	int result = 0;
 	acpi_status status = 0;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-	struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF),
-		ACPI_BATTERY_FORMAT_BIF
-	};
-	union acpi_object *package = NULL;
-	struct acpi_buffer *data = NULL;
-	struct acpi_battery_info *bif = NULL;
 
 	battery->update_time[ACPI_BATTERY_INFO] = get_seconds();
-
 	if (!acpi_battery_present(battery))
 		return 0;
-
-	/* Evaluate _BIF */
 	mutex_lock(&battery->lock);
 	status = acpi_evaluate_object(acpi_battery_handle(battery), "_BIF",
 				      NULL, &buffer);
@@ -244,28 +239,9 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF"));
 		return -ENODEV;
 	}
-
-	package = buffer.pointer;
-
-	data = &battery->bif_data;
-
-	/* Extract Package Data */
-
-	result =
-	    acpi_battery_extract_package(battery, package, &format, data,
-					 "_BIF");
-	if (result)
-		goto end;
-
-      end:
-
+	result = extract_package(battery, buffer.pointer,
+				 info_offsets, ARRAY_SIZE(info_offsets));
 	kfree(buffer.pointer);
-
-	if (!result) {
-		bif = data->pointer;
-		battery->flags.power_unit = bif->power_unit;
-	}
-
 	return result;
 }
 
@@ -274,11 +250,6 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 	int result = 0;
 	acpi_status status = 0;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-	struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST),
-		ACPI_BATTERY_FORMAT_BST
-	};
-	union acpi_object *package = NULL;
-	struct acpi_buffer *data = NULL;
 
 	battery->update_time[ACPI_BATTERY_STATE] = get_seconds();
 
@@ -294,22 +265,9 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
 		return -ENODEV;
 	}
-
-	package = buffer.pointer;
-
-	data = &battery->bst_data;
-
-	/* Extract Package Data */
-
-	result =
-	    acpi_battery_extract_package(battery, package, &format, data,
-					 "_BST");
-	if (result)
-		goto end;
-
-      end:
+	result = extract_package(battery, buffer.pointer,
+				 state_offsets, ARRAY_SIZE(state_offsets));
 	kfree(buffer.pointer);
-
 	return result;
 }
 
@@ -332,7 +290,7 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
 	if (!acpi_battery_present(battery))
 		return -ENODEV;
 
-	if (!battery->flags.alarm_present)
+	if (!battery->alarm_present)
 		return -ENODEV;
 
 	arg0.integer.value = alarm;
@@ -356,22 +314,21 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery)
 	int result = 0;
 	acpi_status status = AE_OK;
 	acpi_handle handle = NULL;
-	struct acpi_battery_info *bif = battery->bif_data.pointer;
 	unsigned long alarm = battery->alarm;
 
 	/* See if alarms are supported, and if so, set default */
 
 	status = acpi_get_handle(acpi_battery_handle(battery), "_BTP", &handle);
 	if (ACPI_SUCCESS(status)) {
-		battery->flags.alarm_present = 1;
-		if (!alarm && bif) {
-			alarm = bif->design_capacity_warning;
+		battery->alarm_present = 1;
+		if (!alarm) {
+			alarm = battery->design_capacity_warning;
 		}
 		result = acpi_battery_set_alarm(battery, alarm);
 		if (result)
 			goto end;
 	} else {
-		battery->flags.alarm_present = 0;
+		battery->alarm_present = 0;
 	}
 
       end:
@@ -387,7 +344,7 @@ static int acpi_battery_init_update(struct acpi_battery *battery)
 	if (result)
 		return result;
 
-	battery->flags.battery_present_prev = acpi_battery_present(battery);
+	battery->present_prev = acpi_battery_present(battery);
 
 	if (acpi_battery_present(battery)) {
 		result = acpi_battery_get_info(battery);
@@ -413,7 +370,7 @@ static int acpi_battery_update(struct acpi_battery *battery,
 		update = 1;
 	}
 
-	if (battery->flags.init_update) {
+	if (battery->init_update) {
 		result = acpi_battery_init_update(battery);
 		if (result)
 			goto end;
@@ -422,8 +379,8 @@ static int acpi_battery_update(struct acpi_battery *battery,
 		result = acpi_battery_get_status(battery);
 		if (result)
 			goto end;
-		if ((!battery->flags.battery_present_prev & acpi_battery_present(battery))
-		    || (battery->flags.battery_present_prev & !acpi_battery_present(battery))) {
+		if ((!battery->present_prev & acpi_battery_present(battery))
+		    || (battery->present_prev & !acpi_battery_present(battery))) {
 			result = acpi_battery_init_update(battery);
 			if (result)
 				goto end;
@@ -435,7 +392,7 @@ static int acpi_battery_update(struct acpi_battery *battery,
 
       end:
 
-	battery->flags.init_update = (result != 0);
+	battery->init_update = (result != 0);
 
 	*update_result_ptr = update_result;
 
@@ -446,19 +403,19 @@ static void acpi_battery_notify_update(struct acpi_battery *battery)
 {
 	acpi_battery_get_status(battery);
 
-	if (battery->flags.init_update) {
+	if (battery->init_update) {
 		return;
 	}
 
-	if ((!battery->flags.battery_present_prev &
+	if ((!battery->present_prev &
 	     acpi_battery_present(battery)) ||
-	    (battery->flags.battery_present_prev &
+	    (battery->present_prev &
 	     !acpi_battery_present(battery))) {
-		battery->flags.init_update = 1;
+		battery->init_update = 1;
 	} else {
-		battery->flags.update[ACPI_BATTERY_INFO] = 1;
-		battery->flags.update[ACPI_BATTERY_STATE] = 1;
-		battery->flags.update[ACPI_BATTERY_ALARM] = 1;
+		battery->update[ACPI_BATTERY_INFO] = 1;
+		battery->update[ACPI_BATTERY_STATE] = 1;
+		battery->update[ACPI_BATTERY_ALARM] = 1;
 	}
 }
 
@@ -471,7 +428,6 @@ static struct proc_dir_entry *acpi_battery_dir;
 static int acpi_battery_print_info(struct seq_file *seq, int result)
 {
 	struct acpi_battery *battery = seq->private;
-	struct acpi_battery_info *bif = NULL;
 	char *units = "?";
 
 	if (result)
@@ -484,30 +440,23 @@ static int acpi_battery_print_info(struct seq_file *seq, int result)
 		goto end;
 	}
 
-	bif = battery->bif_data.pointer;
-	if (!bif) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BIF buffer is NULL"));
-		result = -ENODEV;
-		goto end;
-	}
-
 	/* Battery Units */
 
 	units = acpi_battery_power_units(battery);
 
-	if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
+	if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "design capacity:         unknown\n");
 	else
 		seq_printf(seq, "design capacity:         %d %sh\n",
-			   (u32) bif->design_capacity, units);
+			   (u32) battery->design_capacity, units);
 
-	if (bif->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
+	if (battery->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "last full capacity:      unknown\n");
 	else
 		seq_printf(seq, "last full capacity:      %d %sh\n",
-			   (u32) bif->last_full_capacity, units);
+			   (u32) battery->last_full_capacity, units);
 
-	switch ((u32) bif->battery_technology) {
+	switch ((u32) battery->technology) {
 	case 0:
 		seq_printf(seq, "battery technology:      non-rechargeable\n");
 		break;
@@ -519,23 +468,23 @@ static int acpi_battery_print_info(struct seq_file *seq, int result)
 		break;
 	}
 
-	if (bif->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
+	if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "design voltage:          unknown\n");
 	else
 		seq_printf(seq, "design voltage:          %d mV\n",
-			   (u32) bif->design_voltage);
+			   (u32) battery->design_voltage);
 	seq_printf(seq, "design capacity warning: %d %sh\n",
-		   (u32) bif->design_capacity_warning, units);
+		   (u32) battery->design_capacity_warning, units);
 	seq_printf(seq, "design capacity low:     %d %sh\n",
-		   (u32) bif->design_capacity_low, units);
+		   (u32) battery->design_capacity_low, units);
 	seq_printf(seq, "capacity granularity 1:  %d %sh\n",
-		   (u32) bif->battery_capacity_granularity_1, units);
+		   (u32) battery->capacity_granularity_1, units);
 	seq_printf(seq, "capacity granularity 2:  %d %sh\n",
-		   (u32) bif->battery_capacity_granularity_2, units);
-	seq_printf(seq, "model number:            %s\n", bif->model_number);
-	seq_printf(seq, "serial number:           %s\n", bif->serial_number);
-	seq_printf(seq, "battery type:            %s\n", bif->battery_type);
-	seq_printf(seq, "OEM info:                %s\n", bif->oem_info);
+		   (u32) battery->capacity_granularity_2, units);
+	seq_printf(seq, "model number:            %s\n", battery->model_number);
+	seq_printf(seq, "serial number:           %s\n", battery->serial_number);
+	seq_printf(seq, "battery type:            %s\n", battery->type);
+	seq_printf(seq, "OEM info:                %s\n", battery->oem_info);
 
       end:
 
@@ -548,7 +497,6 @@ static int acpi_battery_print_info(struct seq_file *seq, int result)
 static int acpi_battery_print_state(struct seq_file *seq, int result)
 {
 	struct acpi_battery *battery = seq->private;
-	struct acpi_battery_state *bst = NULL;
 	char *units = "?";
 
 	if (result)
@@ -561,50 +509,43 @@ static int acpi_battery_print_state(struct seq_file *seq, int result)
 		goto end;
 	}
 
-	bst = battery->bst_data.pointer;
-	if (!bst) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BST buffer is NULL"));
-		result = -ENODEV;
-		goto end;
-	}
-
 	/* Battery Units */
 
 	units = acpi_battery_power_units(battery);
 
-	if (!(bst->state & 0x04))
+	if (!(battery->state & 0x04))
 		seq_printf(seq, "capacity state:          ok\n");
 	else
 		seq_printf(seq, "capacity state:          critical\n");
 
-	if ((bst->state & 0x01) && (bst->state & 0x02)) {
+	if ((battery->state & 0x01) && (battery->state & 0x02)) {
 		seq_printf(seq,
 			   "charging state:          charging/discharging\n");
-	} else if (bst->state & 0x01)
+	} else if (battery->state & 0x01)
 		seq_printf(seq, "charging state:          discharging\n");
-	else if (bst->state & 0x02)
+	else if (battery->state & 0x02)
 		seq_printf(seq, "charging state:          charging\n");
 	else {
 		seq_printf(seq, "charging state:          charged\n");
 	}
 
-	if (bst->present_rate == ACPI_BATTERY_VALUE_UNKNOWN)
+	if (battery->present_rate == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "present rate:            unknown\n");
 	else
 		seq_printf(seq, "present rate:            %d %s\n",
-			   (u32) bst->present_rate, units);
+			   (u32) battery->present_rate, units);
 
-	if (bst->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
+	if (battery->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "remaining capacity:      unknown\n");
 	else
 		seq_printf(seq, "remaining capacity:      %d %sh\n",
-			   (u32) bst->remaining_capacity, units);
+			   (u32) battery->remaining_capacity, units);
 
-	if (bst->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
+	if (battery->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "present voltage:         unknown\n");
 	else
 		seq_printf(seq, "present voltage:         %d mV\n",
-			   (u32) bst->present_voltage);
+			   (u32) battery->present_voltage);
 
       end:
 
@@ -713,7 +654,7 @@ static int acpi_battery_read(int fid, struct seq_file *seq)
 	int update = 0;
 
 	update = (get_seconds() - battery->update_time[fid] >= update_time);
-	update = (update | battery->flags.update[fid]);
+	update = (update | battery->update[fid]);
 
 	result = acpi_battery_update(battery, update, &update_result);
 	if (result)
@@ -728,7 +669,7 @@ static int acpi_battery_read(int fid, struct seq_file *seq)
       end:
 	result = acpi_read_funcs[fid].print(seq, result);
 	acpi_battery_check_result(battery, result);
-	battery->flags.update[fid] = result;
+	battery->update[fid] = result;
 	return result;
 }
 
@@ -902,7 +843,7 @@ static int acpi_battery_add(struct acpi_device *device)
 	if (result)
 		goto end;
 
-	battery->flags.init_update = 1;
+	battery->init_update = 1;
 
 	result = acpi_battery_add_fs(device);
 	if (result)
@@ -948,10 +889,6 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
 
 	acpi_battery_remove_fs(device);
 
-	kfree(battery->bif_data.pointer);
-
-	kfree(battery->bst_data.pointer);
-
 	mutex_destroy(&battery->lock);
 
 	kfree(battery);
@@ -969,7 +906,7 @@ static int acpi_battery_resume(struct acpi_device *device)
 
 	battery = device->driver_data;
 
-	battery->flags.init_update = 1;
+	battery->init_update = 1;
 
 	return 0;
 }


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

* [PATCH 03/12] ACPI: Battery: simplify update scheme
  2007-08-16 14:25 [PATCH 01/12] ACPI: AC: Add sysfs interface Alexey Starikovskiy
  2007-08-16 14:26 ` [PATCH 02/12] ACPI: Battery: don't use acpi_extract_package() Alexey Starikovskiy
@ 2007-08-16 14:26 ` Alexey Starikovskiy
  2007-08-16 14:26 ` [PATCH 04/12] ACPI: Battery: Misc clean-ups, no functional changes Alexey Starikovskiy
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Alexey Starikovskiy @ 2007-08-16 14:26 UTC (permalink / raw)
  To: lenb, linux-acpi; +Cc: astarikovskiy

Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
---

 drivers/acpi/battery.c |  274 +++++++++---------------------------------------
 1 files changed, 52 insertions(+), 222 deletions(-)

diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 14bdfad..eea4dd9 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -27,6 +27,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
+#include <linux/jiffies.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <asm/uaccess.h>
@@ -41,27 +42,18 @@
 #define ACPI_BATTERY_DEVICE_NAME	"Battery"
 #define ACPI_BATTERY_NOTIFY_STATUS	0x80
 #define ACPI_BATTERY_NOTIFY_INFO	0x81
-#define ACPI_BATTERY_UNITS_WATTS	"mW"
-#define ACPI_BATTERY_UNITS_AMPS		"mA"
 
 #define _COMPONENT		ACPI_BATTERY_COMPONENT
 
-#define ACPI_BATTERY_UPDATE_TIME	0
-
-#define ACPI_BATTERY_NONE_UPDATE	0
-#define ACPI_BATTERY_EASY_UPDATE	1
-#define ACPI_BATTERY_INIT_UPDATE	2
-
 ACPI_MODULE_NAME("battery");
 
 MODULE_AUTHOR("Paul Diefenbaugh");
 MODULE_DESCRIPTION("ACPI Battery Driver");
 MODULE_LICENSE("GPL");
 
-static unsigned int update_time = ACPI_BATTERY_UPDATE_TIME;
-
-/* 0 - every time, > 0 - by update_time */
-module_param(update_time, uint, 0644);
+static unsigned int cache_time = 1000;
+module_param(cache_time, uint, 0644);
+MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
 
 extern struct proc_dir_entry *acpi_lock_battery_dir(void);
 extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
@@ -95,15 +87,12 @@ enum acpi_battery_files {
 };
 
 struct acpi_battery {
-	struct acpi_device *device;
 	struct mutex lock;
-	unsigned long alarm;
-	unsigned long update_time[ACPI_BATTERY_NUMFILES];
-	int state;
+	struct acpi_device *device;
+	unsigned long update_time;
 	int present_rate;
 	int remaining_capacity;
 	int present_voltage;
-	int power_unit;
 	int design_capacity;
 	int last_full_capacity;
 	int technology;
@@ -112,14 +101,14 @@ struct acpi_battery {
 	int design_capacity_low;
 	int capacity_granularity_1;
 	int capacity_granularity_2;
+	int alarm;
 	char model_number[32];
 	char serial_number[32];
 	char type[32];
 	char oem_info[32];
-	u8 present_prev;
+	int state;
+	int power_unit;
 	u8 alarm_present;
-	u8 init_update;
-	u8 update[ACPI_BATTERY_NUMFILES];
 };
 
 inline int acpi_battery_present(struct acpi_battery *battery)
@@ -127,33 +116,15 @@ inline int acpi_battery_present(struct acpi_battery *battery)
 	return battery->device->status.battery_present;
 }
 
-inline char *acpi_battery_power_units(struct acpi_battery *battery)
+inline char *acpi_battery_units(struct acpi_battery *battery)
 {
-	if (battery->power_unit)
-		return ACPI_BATTERY_UNITS_AMPS;
-	else
-		return ACPI_BATTERY_UNITS_WATTS;
-}
-
-inline acpi_handle acpi_battery_handle(struct acpi_battery *battery)
-{
-	return battery->device->handle;
+	return (battery->power_unit)?"mA":"mW";
 }
 
 /* --------------------------------------------------------------------------
                                Battery Management
    -------------------------------------------------------------------------- */
 
-static void acpi_battery_check_result(struct acpi_battery *battery, int result)
-{
-	if (!battery)
-		return;
-
-	if (result) {
-		battery->init_update = 1;
-	}
-}
-
 struct acpi_offsets {
 	size_t offset;		/* offset inside struct acpi_sbs_battery */
 	u8 mode;		/* int or string? */
@@ -228,11 +199,10 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 	acpi_status status = 0;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 
-	battery->update_time[ACPI_BATTERY_INFO] = get_seconds();
 	if (!acpi_battery_present(battery))
 		return 0;
 	mutex_lock(&battery->lock);
-	status = acpi_evaluate_object(acpi_battery_handle(battery), "_BIF",
+	status = acpi_evaluate_object(battery->device->handle, "_BIF",
 				      NULL, &buffer);
 	mutex_unlock(&battery->lock);
 	if (ACPI_FAILURE(status)) {
@@ -251,14 +221,17 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 	acpi_status status = 0;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 
-	battery->update_time[ACPI_BATTERY_STATE] = get_seconds();
-
 	if (!acpi_battery_present(battery))
 		return 0;
 
+	if (battery->update_time &&
+	    time_before(jiffies, battery->update_time +
+			msecs_to_jiffies(cache_time)))
+		return 0;
+
 	/* Evaluate _BST */
 	mutex_lock(&battery->lock);
-	status = acpi_evaluate_object(acpi_battery_handle(battery), "_BST",
+	status = acpi_evaluate_object(battery->device->handle, "_BST",
 				      NULL, &buffer);
 	mutex_unlock(&battery->lock);
 	if (ACPI_FAILURE(status)) {
@@ -267,14 +240,13 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 	}
 	result = extract_package(battery, buffer.pointer,
 				 state_offsets, ARRAY_SIZE(state_offsets));
+	battery->update_time = jiffies;
 	kfree(buffer.pointer);
 	return result;
 }
 
 static int acpi_battery_get_alarm(struct acpi_battery *battery)
 {
-	battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
-
 	return 0;
 }
 
@@ -285,8 +257,6 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
 	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
 	struct acpi_object_list arg_list = { 1, &arg0 };
 
-	battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
-
 	if (!acpi_battery_present(battery))
 		return -ENODEV;
 
@@ -296,7 +266,7 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
 	arg0.integer.value = alarm;
 
 	mutex_lock(&battery->lock);
-	status = acpi_evaluate_object(acpi_battery_handle(battery), "_BTP",
+	status = acpi_evaluate_object(battery->device->handle, "_BTP",
 				 &arg_list, NULL);
 	mutex_unlock(&battery->lock);
 	if (ACPI_FAILURE(status))
@@ -311,112 +281,36 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
 
 static int acpi_battery_init_alarm(struct acpi_battery *battery)
 {
-	int result = 0;
 	acpi_status status = AE_OK;
 	acpi_handle handle = NULL;
-	unsigned long alarm = battery->alarm;
 
 	/* See if alarms are supported, and if so, set default */
-
-	status = acpi_get_handle(acpi_battery_handle(battery), "_BTP", &handle);
-	if (ACPI_SUCCESS(status)) {
-		battery->alarm_present = 1;
-		if (!alarm) {
-			alarm = battery->design_capacity_warning;
-		}
-		result = acpi_battery_set_alarm(battery, alarm);
-		if (result)
-			goto end;
-	} else {
+	status = acpi_get_handle(battery->device->handle, "_BTP", &handle);
+	if (ACPI_FAILURE(status)) {
 		battery->alarm_present = 0;
+		return 0;
 	}
-
-      end:
-
-	return result;
+	battery->alarm_present = 1;
+	if (!battery->alarm)
+		battery->alarm = battery->design_capacity_warning;
+	return acpi_battery_set_alarm(battery, battery->alarm);
 }
 
-static int acpi_battery_init_update(struct acpi_battery *battery)
+static int acpi_battery_update(struct acpi_battery *battery)
 {
-	int result = 0;
-
-	result = acpi_battery_get_status(battery);
-	if (result)
+	int saved_present = acpi_battery_present(battery);
+	int result = acpi_battery_get_status(battery);
+	if (result || !acpi_battery_present(battery))
 		return result;
-
-	battery->present_prev = acpi_battery_present(battery);
-
-	if (acpi_battery_present(battery)) {
+	if (saved_present != acpi_battery_present(battery) ||
+	    !battery->update_time) {
+		battery->update_time = 0;
 		result = acpi_battery_get_info(battery);
 		if (result)
 			return result;
-		result = acpi_battery_get_state(battery);
-		if (result)
-			return result;
-
 		acpi_battery_init_alarm(battery);
 	}
-
-	return result;
-}
-
-static int acpi_battery_update(struct acpi_battery *battery,
-			       int update, int *update_result_ptr)
-{
-	int result = 0;
-	int update_result = ACPI_BATTERY_NONE_UPDATE;
-
-	if (!acpi_battery_present(battery)) {
-		update = 1;
-	}
-
-	if (battery->init_update) {
-		result = acpi_battery_init_update(battery);
-		if (result)
-			goto end;
-		update_result = ACPI_BATTERY_INIT_UPDATE;
-	} else if (update) {
-		result = acpi_battery_get_status(battery);
-		if (result)
-			goto end;
-		if ((!battery->present_prev & acpi_battery_present(battery))
-		    || (battery->present_prev & !acpi_battery_present(battery))) {
-			result = acpi_battery_init_update(battery);
-			if (result)
-				goto end;
-			update_result = ACPI_BATTERY_INIT_UPDATE;
-		} else {
-			update_result = ACPI_BATTERY_EASY_UPDATE;
-		}
-	}
-
-      end:
-
-	battery->init_update = (result != 0);
-
-	*update_result_ptr = update_result;
-
-	return result;
-}
-
-static void acpi_battery_notify_update(struct acpi_battery *battery)
-{
-	acpi_battery_get_status(battery);
-
-	if (battery->init_update) {
-		return;
-	}
-
-	if ((!battery->present_prev &
-	     acpi_battery_present(battery)) ||
-	    (battery->present_prev &
-	     !acpi_battery_present(battery))) {
-		battery->init_update = 1;
-	} else {
-		battery->update[ACPI_BATTERY_INFO] = 1;
-		battery->update[ACPI_BATTERY_STATE] = 1;
-		battery->update[ACPI_BATTERY_ALARM] = 1;
-	}
+	return acpi_battery_get_state(battery);
 }
 
 /* --------------------------------------------------------------------------
@@ -442,7 +336,7 @@ static int acpi_battery_print_info(struct seq_file *seq, int result)
 
 	/* Battery Units */
 
-	units = acpi_battery_power_units(battery);
+	units = acpi_battery_units(battery);
 
 	if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "design capacity:         unknown\n");
@@ -511,7 +405,7 @@ static int acpi_battery_print_state(struct seq_file *seq, int result)
 
 	/* Battery Units */
 
-	units = acpi_battery_power_units(battery);
+	units = acpi_battery_units(battery);
 
 	if (!(battery->state & 0x04))
 		seq_printf(seq, "capacity state:          ok\n");
@@ -571,13 +465,13 @@ static int acpi_battery_print_alarm(struct seq_file *seq, int result)
 
 	/* Battery Units */
 
-	units = acpi_battery_power_units(battery);
+	units = acpi_battery_units(battery);
 
 	seq_printf(seq, "alarm:                   ");
 	if (!battery->alarm)
 		seq_printf(seq, "unsupported\n");
 	else
-		seq_printf(seq, "%lu %sh\n", battery->alarm, units);
+		seq_printf(seq, "%u %sh\n", battery->alarm, units);
 
       end:
 
@@ -587,50 +481,35 @@ static int acpi_battery_print_alarm(struct seq_file *seq, int result)
 	return result;
 }
 
-static ssize_t
-acpi_battery_write_alarm(struct file *file,
-			 const char __user * buffer,
-			 size_t count, loff_t * ppos)
+static ssize_t acpi_battery_write_alarm(struct file *file,
+					const char __user * buffer,
+					size_t count, loff_t * ppos)
 {
 	int result = 0;
 	char alarm_string[12] = { '\0' };
 	struct seq_file *m = file->private_data;
 	struct acpi_battery *battery = m->private;
-	int update_result = ACPI_BATTERY_NONE_UPDATE;
 
 	if (!battery || (count > sizeof(alarm_string) - 1))
 		return -EINVAL;
-
-	result = acpi_battery_update(battery, 1, &update_result);
 	if (result) {
 		result = -ENODEV;
 		goto end;
 	}
-
 	if (!acpi_battery_present(battery)) {
 		result = -ENODEV;
 		goto end;
 	}
-
 	if (copy_from_user(alarm_string, buffer, count)) {
 		result = -EFAULT;
 		goto end;
 	}
-
 	alarm_string[count] = '\0';
-
-	result = acpi_battery_set_alarm(battery,
-					simple_strtoul(alarm_string, NULL, 0));
-	if (result)
-		goto end;
-
+	battery->alarm = simple_strtol(alarm_string, NULL, 0);
+	result = acpi_battery_set_alarm(battery, battery->alarm);
       end:
-
-	acpi_battery_check_result(battery, result);
-
 	if (!result)
 		return count;
-
 	return result;
 }
 
@@ -649,28 +528,8 @@ static struct acpi_read_mux {
 static int acpi_battery_read(int fid, struct seq_file *seq)
 {
 	struct acpi_battery *battery = seq->private;
-	int result = 0;
-	int update_result = ACPI_BATTERY_NONE_UPDATE;
-	int update = 0;
-
-	update = (get_seconds() - battery->update_time[fid] >= update_time);
-	update = (update | battery->update[fid]);
-
-	result = acpi_battery_update(battery, update, &update_result);
-	if (result)
-		goto end;
-
-	if (update_result == ACPI_BATTERY_EASY_UPDATE) {
-		result = acpi_read_funcs[fid].get(battery);
-		if (result)
-			goto end;
-	}
-
-      end:
-	result = acpi_read_funcs[fid].print(seq, result);
-	acpi_battery_check_result(battery, result);
-	battery->update[fid] = result;
-	return result;
+	int result = acpi_battery_update(battery);
+	return acpi_read_funcs[fid].print(seq, result);
 }
 
 static int acpi_battery_read_info(struct seq_file *seq, void *offset)
@@ -794,30 +653,11 @@ static int acpi_battery_remove_fs(struct acpi_device *device)
 static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
 {
 	struct acpi_battery *battery = data;
-	struct acpi_device *device = NULL;
-
 	if (!battery)
 		return;
-
-	device = battery->device;
-
-	switch (event) {
-	case ACPI_BATTERY_NOTIFY_STATUS:
-	case ACPI_BATTERY_NOTIFY_INFO:
-	case ACPI_NOTIFY_BUS_CHECK:
-	case ACPI_NOTIFY_DEVICE_CHECK:
-		device = battery->device;
-		acpi_battery_notify_update(battery);
-		acpi_bus_generate_event(device, event,
-					acpi_battery_present(battery));
-		break;
-	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Unsupported event [0x%x]\n", event));
-		break;
-	}
-
-	return;
+	acpi_battery_update(battery);
+	acpi_bus_generate_event(battery->device, event,
+				acpi_battery_present(battery));
 }
 
 static int acpi_battery_add(struct acpi_device *device)
@@ -838,13 +678,7 @@ static int acpi_battery_add(struct acpi_device *device)
 	strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
 	acpi_driver_data(device) = battery;
-
-	result = acpi_battery_get_status(battery);
-	if (result)
-		goto end;
-
-	battery->init_update = 1;
-
+	acpi_battery_update(battery);
 	result = acpi_battery_add_fs(device);
 	if (result)
 		goto end;
@@ -900,14 +734,10 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
 static int acpi_battery_resume(struct acpi_device *device)
 {
 	struct acpi_battery *battery;
-
 	if (!device)
 		return -EINVAL;
-
-	battery = device->driver_data;
-
-	battery->init_update = 1;
-
+	battery = acpi_driver_data(device);
+	battery->update_time = 0;
 	return 0;
 }
 


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

* [PATCH 04/12] ACPI: Battery: Misc clean-ups, no functional changes
  2007-08-16 14:25 [PATCH 01/12] ACPI: AC: Add sysfs interface Alexey Starikovskiy
  2007-08-16 14:26 ` [PATCH 02/12] ACPI: Battery: don't use acpi_extract_package() Alexey Starikovskiy
  2007-08-16 14:26 ` [PATCH 03/12] ACPI: Battery: simplify update scheme Alexey Starikovskiy
@ 2007-08-16 14:26 ` Alexey Starikovskiy
  2007-08-16 14:26 ` [PATCH 05/12] ACPI: Battery: Add sysfs support Alexey Starikovskiy
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Alexey Starikovskiy @ 2007-08-16 14:26 UTC (permalink / raw)
  To: lenb, linux-acpi; +Cc: astarikovskiy

Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
---

 drivers/acpi/battery.c |  346 +++++++++++++++++-------------------------------
 1 files changed, 126 insertions(+), 220 deletions(-)

diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index eea4dd9..0a20e80 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -1,6 +1,8 @@
 /*
- *  acpi_battery.c - ACPI Battery Driver ($Revision: 37 $)
+ *  battery.c - ACPI Battery Driver (Revision: 2.0)
  *
+ *  Copyright (C) 2007 Alexey Starikovskiy <astarikovskiy@suse.de>
+ *  Copyright (C) 2004-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com>
  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
  *
@@ -48,6 +50,7 @@
 ACPI_MODULE_NAME("battery");
 
 MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>");
 MODULE_DESCRIPTION("ACPI Battery Driver");
 MODULE_LICENSE("GPL");
 
@@ -58,31 +61,17 @@ MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
 extern struct proc_dir_entry *acpi_lock_battery_dir(void);
 extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
 
-static int acpi_battery_add(struct acpi_device *device);
-static int acpi_battery_remove(struct acpi_device *device, int type);
-static int acpi_battery_resume(struct acpi_device *device);
-
 static const struct acpi_device_id battery_device_ids[] = {
 	{"PNP0C0A", 0},
 	{"", 0},
 };
-MODULE_DEVICE_TABLE(acpi, battery_device_ids);
 
-static struct acpi_driver acpi_battery_driver = {
-	.name = "battery",
-	.class = ACPI_BATTERY_CLASS,
-	.ids = battery_device_ids,
-	.ops = {
-		.add = acpi_battery_add,
-		.resume = acpi_battery_resume,
-		.remove = acpi_battery_remove,
-		},
-};
+MODULE_DEVICE_TABLE(acpi, battery_device_ids);
 
 enum acpi_battery_files {
-	ACPI_BATTERY_INFO = 0,
-	ACPI_BATTERY_STATE,
-	ACPI_BATTERY_ALARM,
+	info_tag = 0,
+	state_tag,
+	alarm_tag,
 	ACPI_BATTERY_NUMFILES,
 };
 
@@ -124,7 +113,6 @@ inline char *acpi_battery_units(struct acpi_battery *battery)
 /* --------------------------------------------------------------------------
                                Battery Management
    -------------------------------------------------------------------------- */
-
 struct acpi_offsets {
 	size_t offset;		/* offset inside struct acpi_sbs_battery */
 	u8 mode;		/* int or string? */
@@ -183,19 +171,16 @@ static int extract_package(struct acpi_battery *battery,
 
 static int acpi_battery_get_status(struct acpi_battery *battery)
 {
-	int result = 0;
-
-	result = acpi_bus_get_status(battery->device);
-	if (result) {
+	if (acpi_bus_get_status(battery->device)) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA"));
 		return -ENODEV;
 	}
-	return result;
+	return 0;
 }
 
 static int acpi_battery_get_info(struct acpi_battery *battery)
 {
-	int result = 0;
+	int result = -EFAULT;
 	acpi_status status = 0;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 
@@ -205,10 +190,12 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 	status = acpi_evaluate_object(battery->device->handle, "_BIF",
 				      NULL, &buffer);
 	mutex_unlock(&battery->lock);
+
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF"));
 		return -ENODEV;
 	}
+
 	result = extract_package(battery, buffer.pointer,
 				 info_offsets, ARRAY_SIZE(info_offsets));
 	kfree(buffer.pointer);
@@ -234,10 +221,12 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 	status = acpi_evaluate_object(battery->device->handle, "_BST",
 				      NULL, &buffer);
 	mutex_unlock(&battery->lock);
+
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
 		return -ENODEV;
 	}
+
 	result = extract_package(battery, buffer.pointer,
 				 state_offsets, ARRAY_SIZE(state_offsets));
 	battery->update_time = jiffies;
@@ -245,37 +234,26 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 	return result;
 }
 
-static int acpi_battery_get_alarm(struct acpi_battery *battery)
-{
-	return 0;
-}
-
-static int acpi_battery_set_alarm(struct acpi_battery *battery,
-				  unsigned long alarm)
+static int acpi_battery_set_alarm(struct acpi_battery *battery)
 {
 	acpi_status status = 0;
-	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
+	union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER };
 	struct acpi_object_list arg_list = { 1, &arg0 };
 
-	if (!acpi_battery_present(battery))
-		return -ENODEV;
-
-	if (!battery->alarm_present)
+	if (!acpi_battery_present(battery)|| !battery->alarm_present)
 		return -ENODEV;
 
-	arg0.integer.value = alarm;
+	arg0.integer.value = battery->alarm;
 
 	mutex_lock(&battery->lock);
 	status = acpi_evaluate_object(battery->device->handle, "_BTP",
 				 &arg_list, NULL);
 	mutex_unlock(&battery->lock);
+
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
 
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", (u32) alarm));
-
-	battery->alarm = alarm;
-
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", battery->alarm));
 	return 0;
 }
 
@@ -293,7 +271,7 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery)
 	battery->alarm_present = 1;
 	if (!battery->alarm)
 		battery->alarm = battery->design_capacity_warning;
-	return acpi_battery_set_alarm(battery, battery->alarm);
+	return acpi_battery_set_alarm(battery);
 }
 
 static int acpi_battery_update(struct acpi_battery *battery)
@@ -322,130 +300,101 @@ static struct proc_dir_entry *acpi_battery_dir;
 static int acpi_battery_print_info(struct seq_file *seq, int result)
 {
 	struct acpi_battery *battery = seq->private;
-	char *units = "?";
 
 	if (result)
 		goto end;
 
-	if (acpi_battery_present(battery))
-		seq_printf(seq, "present:                 yes\n");
-	else {
-		seq_printf(seq, "present:                 no\n");
+	seq_printf(seq, "present:                 %s\n",
+		   acpi_battery_present(battery)?"yes":"no");
+	if (!acpi_battery_present(battery))
 		goto end;
-	}
-
-	/* Battery Units */
-
-	units = acpi_battery_units(battery);
-
 	if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "design capacity:         unknown\n");
 	else
 		seq_printf(seq, "design capacity:         %d %sh\n",
-			   (u32) battery->design_capacity, units);
+			   battery->design_capacity,
+			   acpi_battery_units(battery));
 
 	if (battery->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "last full capacity:      unknown\n");
 	else
 		seq_printf(seq, "last full capacity:      %d %sh\n",
-			   (u32) battery->last_full_capacity, units);
-
-	switch ((u32) battery->technology) {
-	case 0:
-		seq_printf(seq, "battery technology:      non-rechargeable\n");
-		break;
-	case 1:
-		seq_printf(seq, "battery technology:      rechargeable\n");
-		break;
-	default:
-		seq_printf(seq, "battery technology:      unknown\n");
-		break;
-	}
+			   battery->last_full_capacity,
+			   acpi_battery_units(battery));
+
+	seq_printf(seq, "battery technology:      %srechargeable\n",
+		   (!battery->technology)?"non-":"");
 
 	if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "design voltage:          unknown\n");
 	else
 		seq_printf(seq, "design voltage:          %d mV\n",
-			   (u32) battery->design_voltage);
+			   battery->design_voltage);
 	seq_printf(seq, "design capacity warning: %d %sh\n",
-		   (u32) battery->design_capacity_warning, units);
+		   battery->design_capacity_warning,
+		   acpi_battery_units(battery));
 	seq_printf(seq, "design capacity low:     %d %sh\n",
-		   (u32) battery->design_capacity_low, units);
+		   battery->design_capacity_low,
+		   acpi_battery_units(battery));
 	seq_printf(seq, "capacity granularity 1:  %d %sh\n",
-		   (u32) battery->capacity_granularity_1, units);
+		   battery->capacity_granularity_1,
+		   acpi_battery_units(battery));
 	seq_printf(seq, "capacity granularity 2:  %d %sh\n",
-		   (u32) battery->capacity_granularity_2, units);
+		   battery->capacity_granularity_2,
+		   acpi_battery_units(battery));
 	seq_printf(seq, "model number:            %s\n", battery->model_number);
 	seq_printf(seq, "serial number:           %s\n", battery->serial_number);
 	seq_printf(seq, "battery type:            %s\n", battery->type);
 	seq_printf(seq, "OEM info:                %s\n", battery->oem_info);
-
       end:
-
 	if (result)
 		seq_printf(seq, "ERROR: Unable to read battery info\n");
-
 	return result;
 }
 
 static int acpi_battery_print_state(struct seq_file *seq, int result)
 {
 	struct acpi_battery *battery = seq->private;
-	char *units = "?";
 
 	if (result)
 		goto end;
 
-	if (acpi_battery_present(battery))
-		seq_printf(seq, "present:                 yes\n");
-	else {
-		seq_printf(seq, "present:                 no\n");
+	seq_printf(seq, "present:                 %s\n",
+		   acpi_battery_present(battery)?"yes":"no");
+	if (!acpi_battery_present(battery))
 		goto end;
-	}
-
-	/* Battery Units */
-
-	units = acpi_battery_units(battery);
-
-	if (!(battery->state & 0x04))
-		seq_printf(seq, "capacity state:          ok\n");
-	else
-		seq_printf(seq, "capacity state:          critical\n");
 
-	if ((battery->state & 0x01) && (battery->state & 0x02)) {
+	seq_printf(seq, "capacity state:          %s\n",
+			(battery->state & 0x04)?"critical":"ok");
+	if ((battery->state & 0x01) && (battery->state & 0x02))
 		seq_printf(seq,
 			   "charging state:          charging/discharging\n");
-	} else if (battery->state & 0x01)
+	else if (battery->state & 0x01)
 		seq_printf(seq, "charging state:          discharging\n");
 	else if (battery->state & 0x02)
 		seq_printf(seq, "charging state:          charging\n");
-	else {
+	else
 		seq_printf(seq, "charging state:          charged\n");
-	}
 
 	if (battery->present_rate == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "present rate:            unknown\n");
 	else
 		seq_printf(seq, "present rate:            %d %s\n",
-			   (u32) battery->present_rate, units);
+			   battery->present_rate, acpi_battery_units(battery));
 
 	if (battery->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "remaining capacity:      unknown\n");
 	else
 		seq_printf(seq, "remaining capacity:      %d %sh\n",
-			   (u32) battery->remaining_capacity, units);
-
+			   battery->remaining_capacity, acpi_battery_units(battery));
 	if (battery->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "present voltage:         unknown\n");
 	else
 		seq_printf(seq, "present voltage:         %d mV\n",
-			   (u32) battery->present_voltage);
-
+			   battery->present_voltage);
       end:
-
-	if (result) {
+	if (result)
 		seq_printf(seq, "ERROR: Unable to read battery state\n");
-	}
 
 	return result;
 }
@@ -453,7 +402,6 @@ static int acpi_battery_print_state(struct seq_file *seq, int result)
 static int acpi_battery_print_alarm(struct seq_file *seq, int result)
 {
 	struct acpi_battery *battery = seq->private;
-	char *units = "?";
 
 	if (result)
 		goto end;
@@ -462,22 +410,15 @@ static int acpi_battery_print_alarm(struct seq_file *seq, int result)
 		seq_printf(seq, "present:                 no\n");
 		goto end;
 	}
-
-	/* Battery Units */
-
-	units = acpi_battery_units(battery);
-
 	seq_printf(seq, "alarm:                   ");
 	if (!battery->alarm)
 		seq_printf(seq, "unsupported\n");
 	else
-		seq_printf(seq, "%u %sh\n", battery->alarm, units);
-
+		seq_printf(seq, "%u %sh\n", battery->alarm,
+				acpi_battery_units(battery));
       end:
-
 	if (result)
 		seq_printf(seq, "ERROR: Unable to read battery alarm\n");
-
 	return result;
 }
 
@@ -506,7 +447,7 @@ static ssize_t acpi_battery_write_alarm(struct file *file,
 	}
 	alarm_string[count] = '\0';
 	battery->alarm = simple_strtol(alarm_string, NULL, 0);
-	result = acpi_battery_set_alarm(battery, battery->alarm);
+	result = acpi_battery_set_alarm(battery);
       end:
 	if (!result)
 		return count;
@@ -514,95 +455,76 @@ static ssize_t acpi_battery_write_alarm(struct file *file,
 }
 
 typedef int(*print_func)(struct seq_file *seq, int result);
-typedef int(*get_func)(struct acpi_battery *battery);
-
-static struct acpi_read_mux {
-	print_func print;
-	get_func get;
-} acpi_read_funcs[ACPI_BATTERY_NUMFILES] = {
-	{.get = acpi_battery_get_info, .print = acpi_battery_print_info},
-	{.get = acpi_battery_get_state, .print = acpi_battery_print_state},
-	{.get = acpi_battery_get_alarm, .print = acpi_battery_print_alarm},
+
+static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = {
+	acpi_battery_print_info,
+	acpi_battery_print_state,
+	acpi_battery_print_alarm,
 };
 
 static int acpi_battery_read(int fid, struct seq_file *seq)
 {
 	struct acpi_battery *battery = seq->private;
 	int result = acpi_battery_update(battery);
-	return acpi_read_funcs[fid].print(seq, result);
-}
-
-static int acpi_battery_read_info(struct seq_file *seq, void *offset)
-{
-	return acpi_battery_read(ACPI_BATTERY_INFO, seq);
+	return acpi_print_funcs[fid](seq, result);
 }
 
-static int acpi_battery_read_state(struct seq_file *seq, void *offset)
-{
-	return acpi_battery_read(ACPI_BATTERY_STATE, seq);
-}
-
-static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
-{
-	return acpi_battery_read(ACPI_BATTERY_ALARM, seq);
+#define DECLARE_FILE_FUNCTIONS(_name) \
+static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \
+{ \
+	return acpi_battery_read(_name##_tag, seq); \
+} \
+static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \
+{ \
+	return single_open(file, acpi_battery_read_##_name, PDE(inode)->data); \
 }
 
-static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
-{
-	return single_open(file, acpi_battery_read_info, PDE(inode)->data);
-}
-
-static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
-{
-	return single_open(file, acpi_battery_read_state, PDE(inode)->data);
-}
+DECLARE_FILE_FUNCTIONS(info);
+DECLARE_FILE_FUNCTIONS(state);
+DECLARE_FILE_FUNCTIONS(alarm);
+
+#undef DECLARE_FILE_FUNCTIONS
+
+#define FILE_DESCRIPTION_RO(_name) \
+	{ \
+	.name = __stringify(_name), \
+	.mode = S_IRUGO, \
+	.ops = { \
+		.open = acpi_battery_##_name##_open_fs, \
+		.read = seq_read, \
+		.llseek = seq_lseek, \
+		.release = single_release, \
+		.owner = THIS_MODULE, \
+		}, \
+	}
 
-static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
-{
-	return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
-}
+#define FILE_DESCRIPTION_RW(_name) \
+	{ \
+	.name = __stringify(_name), \
+	.mode = S_IFREG | S_IRUGO | S_IWUSR, \
+	.ops = { \
+		.open = acpi_battery_##_name##_open_fs, \
+		.read = seq_read, \
+		.llseek = seq_lseek, \
+		.write = acpi_battery_write_##_name, \
+		.release = single_release, \
+		.owner = THIS_MODULE, \
+		}, \
+	}
 
 static struct battery_file {
 	struct file_operations ops;
 	mode_t mode;
 	char *name;
 } acpi_battery_file[] = {
-	{
-	.name = "info",
-	.mode = S_IRUGO,
-	.ops = {
-	.open = acpi_battery_info_open_fs,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-	.owner = THIS_MODULE,
-	},
-	},
-	{
-	.name = "state",
-	.mode = S_IRUGO,
-	.ops = {
-	.open = acpi_battery_state_open_fs,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-	.owner = THIS_MODULE,
-	},
-	},
-	{
-	.name = "alarm",
-	.mode = S_IFREG | S_IRUGO | S_IWUSR,
-	.ops = {
-	.open = acpi_battery_alarm_open_fs,
-	.read = seq_read,
-	.write = acpi_battery_write_alarm,
-	.llseek = seq_lseek,
-	.release = single_release,
-	.owner = THIS_MODULE,
-	},
-	},
+	FILE_DESCRIPTION_RO(info),
+	FILE_DESCRIPTION_RO(state),
+	FILE_DESCRIPTION_RW(alarm),
 };
 
+#undef FILE_DESCRIPTION_RO
+#undef FILE_DESCRIPTION_RW
+
 static int acpi_battery_add_fs(struct acpi_device *device)
 {
 	struct proc_dir_entry *entry = NULL;
@@ -627,23 +549,20 @@ static int acpi_battery_add_fs(struct acpi_device *device)
 			entry->owner = THIS_MODULE;
 		}
 	}
-
 	return 0;
 }
 
-static int acpi_battery_remove_fs(struct acpi_device *device)
+static void acpi_battery_remove_fs(struct acpi_device *device)
 {
 	int i;
-	if (acpi_device_dir(device)) {
-		for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
-			remove_proc_entry(acpi_battery_file[i].name,
+	if (!acpi_device_dir(device))
+		return;
+	for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i)
+		remove_proc_entry(acpi_battery_file[i].name,
 				  acpi_device_dir(device));
-		}
-		remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
-		acpi_device_dir(device) = NULL;
-	}
 
-	return 0;
+	remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
+	acpi_device_dir(device) = NULL;
 }
 
 /* --------------------------------------------------------------------------
@@ -665,14 +584,11 @@ static int acpi_battery_add(struct acpi_device *device)
 	int result = 0;
 	acpi_status status = 0;
 	struct acpi_battery *battery = NULL;
-
 	if (!device)
 		return -EINVAL;
-
 	battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
 	if (!battery)
 		return -ENOMEM;
-
 	mutex_init(&battery->lock);
 	battery->device = device;
 	strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
@@ -682,7 +598,6 @@ static int acpi_battery_add(struct acpi_device *device)
 	result = acpi_battery_add_fs(device);
 	if (result)
 		goto end;
-
 	status = acpi_install_notify_handler(device->handle,
 					     ACPI_ALL_NOTIFY,
 					     acpi_battery_notify, battery);
@@ -691,19 +606,14 @@ static int acpi_battery_add(struct acpi_device *device)
 		result = -ENODEV;
 		goto end;
 	}
-
 	printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
 	       ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
 	       device->status.battery_present ? "present" : "absent");
-
       end:
-
 	if (result) {
 		acpi_battery_remove_fs(device);
 		kfree(battery);
 	}
-
-
 	return result;
 }
 
@@ -714,19 +624,13 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
 
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
-
 	battery = acpi_driver_data(device);
-
 	status = acpi_remove_notify_handler(device->handle,
 					    ACPI_ALL_NOTIFY,
 					    acpi_battery_notify);
-
 	acpi_battery_remove_fs(device);
-
 	mutex_destroy(&battery->lock);
-
 	kfree(battery);
-
 	return 0;
 }
 
@@ -741,33 +645,35 @@ static int acpi_battery_resume(struct acpi_device *device)
 	return 0;
 }
 
+static struct acpi_driver acpi_battery_driver = {
+	.name = "battery",
+	.class = ACPI_BATTERY_CLASS,
+	.ids = battery_device_ids,
+	.ops = {
+		.add = acpi_battery_add,
+		.resume = acpi_battery_resume,
+		.remove = acpi_battery_remove,
+		},
+};
+
 static int __init acpi_battery_init(void)
 {
-	int result;
-
 	if (acpi_disabled)
 		return -ENODEV;
-
 	acpi_battery_dir = acpi_lock_battery_dir();
 	if (!acpi_battery_dir)
 		return -ENODEV;
-
-	result = acpi_bus_register_driver(&acpi_battery_driver);
-	if (result < 0) {
+	if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {
 		acpi_unlock_battery_dir(acpi_battery_dir);
 		return -ENODEV;
 	}
-
 	return 0;
 }
 
 static void __exit acpi_battery_exit(void)
 {
 	acpi_bus_unregister_driver(&acpi_battery_driver);
-
 	acpi_unlock_battery_dir(acpi_battery_dir);
-
-	return;
 }
 
 module_init(acpi_battery_init);


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

* [PATCH 05/12] ACPI: Battery: Add sysfs support
  2007-08-16 14:25 [PATCH 01/12] ACPI: AC: Add sysfs interface Alexey Starikovskiy
                   ` (2 preceding siblings ...)
  2007-08-16 14:26 ` [PATCH 04/12] ACPI: Battery: Misc clean-ups, no functional changes Alexey Starikovskiy
@ 2007-08-16 14:26 ` Alexey Starikovskiy
  2007-08-16 14:26 ` [PATCH 06/12] ACPI: Add acpi_bus_generate_event4() function Alexey Starikovskiy
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Alexey Starikovskiy @ 2007-08-16 14:26 UTC (permalink / raw)
  To: lenb, linux-acpi; +Cc: astarikovskiy

Refer to Documentation/power_supply_class.txt for interface description.

Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
---

 drivers/acpi/battery.c |  201 +++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 179 insertions(+), 22 deletions(-)

diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 0a20e80..2be9f45 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -30,13 +30,21 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/jiffies.h>
+
+#ifdef CONFIG_ACPI_PROC
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <asm/uaccess.h>
+#endif
 
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
+#if defined(CONFIG_POWER_SUPPLY) || defined(CONFIG_POWER_SUPPLY_MODULE)
+#define ENABLE_POWER_SUPPLY
+#include <linux/power_supply.h>
+#endif
+
 #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
 
 #define ACPI_BATTERY_COMPONENT		0x00040000
@@ -58,9 +66,19 @@ static unsigned int cache_time = 1000;
 module_param(cache_time, uint, 0644);
 MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
 
+#ifdef CONFIG_ACPI_PROC
 extern struct proc_dir_entry *acpi_lock_battery_dir(void);
 extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
 
+enum acpi_battery_files {
+	info_tag = 0,
+	state_tag,
+	alarm_tag,
+	ACPI_BATTERY_NUMFILES,
+};
+
+#endif
+
 static const struct acpi_device_id battery_device_ids[] = {
 	{"PNP0C0A", 0},
 	{"", 0},
@@ -68,22 +86,19 @@ static const struct acpi_device_id battery_device_ids[] = {
 
 MODULE_DEVICE_TABLE(acpi, battery_device_ids);
 
-enum acpi_battery_files {
-	info_tag = 0,
-	state_tag,
-	alarm_tag,
-	ACPI_BATTERY_NUMFILES,
-};
 
 struct acpi_battery {
 	struct mutex lock;
+#ifdef ENABLE_POWER_SUPPLY
+	struct power_supply bat;
+#endif
 	struct acpi_device *device;
 	unsigned long update_time;
-	int present_rate;
-	int remaining_capacity;
-	int present_voltage;
+	int current_now;
+	int capacity_now;
+	int voltage_now;
 	int design_capacity;
-	int last_full_capacity;
+	int full_charge_capacity;
 	int technology;
 	int design_voltage;
 	int design_capacity_warning;
@@ -100,15 +115,119 @@ struct acpi_battery {
 	u8 alarm_present;
 };
 
+#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
+
 inline int acpi_battery_present(struct acpi_battery *battery)
 {
 	return battery->device->status.battery_present;
 }
 
+#ifdef ENABLE_POWER_SUPPLY
+static int acpi_battery_technology(struct acpi_battery *battery)
+{
+	if (!strcasecmp("NiCd", battery->type))
+		return POWER_SUPPLY_TECHNOLOGY_NiCd;
+	if (!strcasecmp("NiMH", battery->type))
+		return POWER_SUPPLY_TECHNOLOGY_NiMH;
+	if (!strcasecmp("LION", battery->type))
+		return POWER_SUPPLY_TECHNOLOGY_LION;
+	if (!strcasecmp("LiP", battery->type))
+		return POWER_SUPPLY_TECHNOLOGY_LIPO;
+	return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
+}
+
+static int acpi_battery_get_property(struct power_supply *psy,
+				     enum power_supply_property psp,
+				     union power_supply_propval *val)
+{
+	struct acpi_battery *battery = to_acpi_battery(psy);
+
+	if ((!acpi_battery_present(battery)) &&
+	     psp != POWER_SUPPLY_PROP_PRESENT)
+		return -ENODEV;
+	switch (psp) {
+	case POWER_SUPPLY_PROP_STATUS:
+		if (battery->state & 0x01)
+			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+		else if (battery->state & 0x02)
+			val->intval = POWER_SUPPLY_STATUS_CHARGING;
+		else if (battery->state == 0)
+			val->intval = POWER_SUPPLY_STATUS_FULL;
+		break;
+	case POWER_SUPPLY_PROP_PRESENT:
+		val->intval = acpi_battery_present(battery);
+		break;
+	case POWER_SUPPLY_PROP_TECHNOLOGY:
+		val->intval = acpi_battery_technology(battery);
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+		val->intval = battery->design_voltage * 1000;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		val->intval = battery->voltage_now * 1000;
+		break;
+	case POWER_SUPPLY_PROP_CURRENT_NOW:
+		val->intval = battery->current_now * 1000;
+		break;
+	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
+	case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
+		val->intval = battery->design_capacity * 1000;
+		break;
+	case POWER_SUPPLY_PROP_CHARGE_FULL:
+	case POWER_SUPPLY_PROP_ENERGY_FULL:
+		val->intval = battery->full_charge_capacity * 1000;
+		break;
+	case POWER_SUPPLY_PROP_CHARGE_NOW:
+	case POWER_SUPPLY_PROP_ENERGY_NOW:
+		val->intval = battery->capacity_now * 1000;
+		break;
+	case POWER_SUPPLY_PROP_MODEL_NAME:
+		val->strval = battery->model_number;
+		break;
+	case POWER_SUPPLY_PROP_MANUFACTURER:
+		val->strval = battery->oem_info;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static enum power_supply_property charge_battery_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+	POWER_SUPPLY_PROP_CHARGE_FULL,
+	POWER_SUPPLY_PROP_CHARGE_NOW,
+	POWER_SUPPLY_PROP_MODEL_NAME,
+	POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+static enum power_supply_property energy_battery_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
+	POWER_SUPPLY_PROP_ENERGY_FULL,
+	POWER_SUPPLY_PROP_ENERGY_NOW,
+	POWER_SUPPLY_PROP_MODEL_NAME,
+	POWER_SUPPLY_PROP_MANUFACTURER,
+};
+#endif
+
+#ifdef CONFIG_ACPI_PROC
 inline char *acpi_battery_units(struct acpi_battery *battery)
 {
 	return (battery->power_unit)?"mA":"mW";
 }
+#endif
 
 /* --------------------------------------------------------------------------
                                Battery Management
@@ -120,15 +239,15 @@ struct acpi_offsets {
 
 static struct acpi_offsets state_offsets[] = {
 	{offsetof(struct acpi_battery, state), 0},
-	{offsetof(struct acpi_battery, present_rate), 0},
-	{offsetof(struct acpi_battery, remaining_capacity), 0},
-	{offsetof(struct acpi_battery, present_voltage), 0},
+	{offsetof(struct acpi_battery, current_now), 0},
+	{offsetof(struct acpi_battery, capacity_now), 0},
+	{offsetof(struct acpi_battery, voltage_now), 0},
 };
 
 static struct acpi_offsets info_offsets[] = {
 	{offsetof(struct acpi_battery, power_unit), 0},
 	{offsetof(struct acpi_battery, design_capacity), 0},
-	{offsetof(struct acpi_battery, last_full_capacity), 0},
+	{offsetof(struct acpi_battery, full_charge_capacity), 0},
 	{offsetof(struct acpi_battery, technology), 0},
 	{offsetof(struct acpi_battery, design_voltage), 0},
 	{offsetof(struct acpi_battery, design_capacity_warning), 0},
@@ -286,6 +405,17 @@ static int acpi_battery_update(struct acpi_battery *battery)
 		result = acpi_battery_get_info(battery);
 		if (result)
 			return result;
+#ifdef ENABLE_POWER_SUPPLY
+		if (battery->power_unit) {
+			battery->bat.properties = charge_battery_props;
+			battery->bat.num_properties =
+				ARRAY_SIZE(charge_battery_props);
+		} else {
+			battery->bat.properties = energy_battery_props;
+			battery->bat.num_properties =
+				ARRAY_SIZE(energy_battery_props);
+		}
+#endif
 		acpi_battery_init_alarm(battery);
 	}
 	return acpi_battery_get_state(battery);
@@ -295,6 +425,7 @@ static int acpi_battery_update(struct acpi_battery *battery)
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
 
+#ifdef CONFIG_ACPI_PROC
 static struct proc_dir_entry *acpi_battery_dir;
 
 static int acpi_battery_print_info(struct seq_file *seq, int result)
@@ -315,11 +446,11 @@ static int acpi_battery_print_info(struct seq_file *seq, int result)
 			   battery->design_capacity,
 			   acpi_battery_units(battery));
 
-	if (battery->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
+	if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "last full capacity:      unknown\n");
 	else
 		seq_printf(seq, "last full capacity:      %d %sh\n",
-			   battery->last_full_capacity,
+			   battery->full_charge_capacity,
 			   acpi_battery_units(battery));
 
 	seq_printf(seq, "battery technology:      %srechargeable\n",
@@ -376,22 +507,22 @@ static int acpi_battery_print_state(struct seq_file *seq, int result)
 	else
 		seq_printf(seq, "charging state:          charged\n");
 
-	if (battery->present_rate == ACPI_BATTERY_VALUE_UNKNOWN)
+	if (battery->current_now == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "present rate:            unknown\n");
 	else
 		seq_printf(seq, "present rate:            %d %s\n",
-			   battery->present_rate, acpi_battery_units(battery));
+			   battery->current_now, acpi_battery_units(battery));
 
-	if (battery->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
+	if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "remaining capacity:      unknown\n");
 	else
 		seq_printf(seq, "remaining capacity:      %d %sh\n",
-			   battery->remaining_capacity, acpi_battery_units(battery));
-	if (battery->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
+			   battery->capacity_now, acpi_battery_units(battery));
+	if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "present voltage:         unknown\n");
 	else
 		seq_printf(seq, "present voltage:         %d mV\n",
-			   battery->present_voltage);
+			   battery->voltage_now);
       end:
 	if (result)
 		seq_printf(seq, "ERROR: Unable to read battery state\n");
@@ -565,6 +696,7 @@ static void acpi_battery_remove_fs(struct acpi_device *device)
 	acpi_device_dir(device) = NULL;
 }
 
+#endif
 /* --------------------------------------------------------------------------
                                  Driver Interface
    -------------------------------------------------------------------------- */
@@ -577,6 +709,9 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
 	acpi_battery_update(battery);
 	acpi_bus_generate_event(battery->device, event,
 				acpi_battery_present(battery));
+#ifdef ENABLE_POWER_SUPPLY
+		kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE);
+#endif
 }
 
 static int acpi_battery_add(struct acpi_device *device)
@@ -595,9 +730,17 @@ static int acpi_battery_add(struct acpi_device *device)
 	strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
 	acpi_driver_data(device) = battery;
 	acpi_battery_update(battery);
+#ifdef CONFIG_ACPI_PROC
 	result = acpi_battery_add_fs(device);
 	if (result)
 		goto end;
+#endif
+#ifdef ENABLE_POWER_SUPPLY
+	battery->bat.name = acpi_device_bid(device);
+	battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
+	battery->bat.get_property = acpi_battery_get_property;
+	result = power_supply_register(&battery->device->dev, &battery->bat);
+#endif
 	status = acpi_install_notify_handler(device->handle,
 					     ACPI_ALL_NOTIFY,
 					     acpi_battery_notify, battery);
@@ -611,7 +754,9 @@ static int acpi_battery_add(struct acpi_device *device)
 	       device->status.battery_present ? "present" : "absent");
       end:
 	if (result) {
+#ifdef CONFIG_ACPI_PROC
 		acpi_battery_remove_fs(device);
+#endif
 		kfree(battery);
 	}
 	return result;
@@ -628,7 +773,13 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
 	status = acpi_remove_notify_handler(device->handle,
 					    ACPI_ALL_NOTIFY,
 					    acpi_battery_notify);
+#ifdef CONFIG_ACPI_PROC
 	acpi_battery_remove_fs(device);
+#endif
+#ifdef ENABLE_POWER_SUPPLY
+	if (battery->bat.dev)
+		power_supply_unregister(&battery->bat);
+#endif
 	mutex_destroy(&battery->lock);
 	kfree(battery);
 	return 0;
@@ -660,11 +811,15 @@ static int __init acpi_battery_init(void)
 {
 	if (acpi_disabled)
 		return -ENODEV;
+#ifdef CONFIG_ACPI_PROC
 	acpi_battery_dir = acpi_lock_battery_dir();
 	if (!acpi_battery_dir)
 		return -ENODEV;
+#endif
 	if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {
+#ifdef CONFIG_ACPI_PROC
 		acpi_unlock_battery_dir(acpi_battery_dir);
+#endif
 		return -ENODEV;
 	}
 	return 0;
@@ -673,7 +828,9 @@ static int __init acpi_battery_init(void)
 static void __exit acpi_battery_exit(void)
 {
 	acpi_bus_unregister_driver(&acpi_battery_driver);
+#ifdef CONFIG_ACPI_PROC
 	acpi_unlock_battery_dir(acpi_battery_dir);
+#endif
 }
 
 module_init(acpi_battery_init);


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

* [PATCH 06/12] ACPI: Add acpi_bus_generate_event4() function
  2007-08-16 14:25 [PATCH 01/12] ACPI: AC: Add sysfs interface Alexey Starikovskiy
                   ` (3 preceding siblings ...)
  2007-08-16 14:26 ` [PATCH 05/12] ACPI: Battery: Add sysfs support Alexey Starikovskiy
@ 2007-08-16 14:26 ` Alexey Starikovskiy
  2007-08-16 14:26 ` [PATCH 07/12] ACPI: EC: Add new query handler to list head Alexey Starikovskiy
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Alexey Starikovskiy @ 2007-08-16 14:26 UTC (permalink / raw)
  To: lenb, linux-acpi; +Cc: astarikovskiy

From: Alexey Starikovskiy <astarikovskiy@suse.de>

acpi_bus_generate_event() takes two strings out of passed device object.
SBS needs to supply these strings directly.

Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
---

 drivers/acpi/bus.c      |   25 ++++++++++++++++---------
 drivers/acpi/event.c    |    7 ++++---
 drivers/acpi/sbs.c      |   39 ++++++++-------------------------------
 include/acpi/acpi_bus.h |    6 ++++--
 4 files changed, 32 insertions(+), 45 deletions(-)

diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 6b2658c..992bb30 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -283,16 +283,12 @@ DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue);
 
 extern int event_is_open;
 
-int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data)
+int acpi_bus_generate_event4(const char *device_class, const char *bus_id, u8 type, int data)
 {
-	struct acpi_bus_event *event = NULL;
+	struct acpi_bus_event *event;
 	unsigned long flags = 0;
 
-
-	if (!device)
-		return -EINVAL;
-
-	if (acpi_bus_generate_genetlink_event(device, type, data))
+	if (acpi_bus_generate_genetlink_event(device_class, bus_id, type, data))
 		printk(KERN_WARNING PREFIX
 			"Failed to generate an ACPI event via genetlink!\n");
 
@@ -304,8 +300,8 @@ int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data)
 	if (!event)
 		return -ENOMEM;
 
-	strcpy(event->device_class, device->pnp.device_class);
-	strcpy(event->bus_id, device->pnp.bus_id);
+	strcpy(event->device_class, device_class);
+	strcpy(event->bus_id, bus_id);
 	event->type = type;
 	event->data = data;
 
@@ -316,6 +312,17 @@ int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data)
 	wake_up_interruptible(&acpi_bus_event_queue);
 
 	return 0;
+
+}
+
+EXPORT_SYMBOL_GPL(acpi_bus_generate_event4);
+
+int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data)
+{
+	if (!device)
+		return -EINVAL;
+	return acpi_bus_generate_event4(device->pnp.device_class,
+					device->pnp.bus_id, type, data);
 }
 
 EXPORT_SYMBOL(acpi_bus_generate_event);
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c
index 95637a4..6529280 100644
--- a/drivers/acpi/event.c
+++ b/drivers/acpi/event.c
@@ -147,7 +147,8 @@ static struct genl_multicast_group acpi_event_mcgrp = {
 	.name = ACPI_GENL_MCAST_GROUP_NAME,
 };
 
-int acpi_bus_generate_genetlink_event(struct acpi_device *device,
+int acpi_bus_generate_genetlink_event(const char *device_class,
+				      const char *bus_id,
 				      u8 type, int data)
 {
 	struct sk_buff *skb;
@@ -191,8 +192,8 @@ int acpi_bus_generate_genetlink_event(struct acpi_device *device,
 
 	memset(event, 0, sizeof(struct acpi_genl_event));
 
-	strcpy(event->device_class, device->pnp.device_class);
-	strcpy(event->bus_id, device->dev.bus_id);
+	strcpy(event->device_class, device_class);
+	strcpy(event->bus_id, bus_id);
 	event->type = type;
 	event->data = data;
 
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 82c3a55..88af657 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -427,27 +427,6 @@ static int acpi_check_update_proc(struct acpi_sbs *sbs)
 	return 0;
 }
 
-static int acpi_sbs_generate_event(struct acpi_device *device,
-				   int event, int state, char *bid, char *class)
-{
-	char bid_saved[5];
-	char class_saved[20];
-	int result = 0;
-
-	strcpy(bid_saved, acpi_device_bid(device));
-	strcpy(class_saved, acpi_device_class(device));
-
-	strcpy(acpi_device_bid(device), bid);
-	strcpy(acpi_device_class(device), class);
-
-	result = acpi_bus_generate_event(device, event, state);
-
-	strcpy(acpi_device_bid(device), bid_saved);
-	strcpy(acpi_device_class(device), class_saved);
-
-	return result;
-}
-
 static int acpi_battery_get_present(struct acpi_battery *battery)
 {
 	s16 state;
@@ -1451,14 +1430,13 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)
 	}
 
 	if (do_ac_init) {
-		result = acpi_sbs_generate_event(sbs->device,
-						 ACPI_SBS_AC_NOTIFY_STATUS,
-						 new_ac_present,
+		result = acpi_bus_generate_event4(ACPI_AC_CLASS,
 						 ACPI_AC_DIR_NAME,
-						 ACPI_AC_CLASS);
+						 ACPI_SBS_AC_NOTIFY_STATUS,
+						 new_ac_present);
 		if (result) {
 			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_sbs_generate_event() failed"));
+					"acpi_bus_generate_event4() failed"));
 		}
 	}
 
@@ -1567,14 +1545,13 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)
 		    old_remaining_capacity !=
 		    battery->state.remaining_capacity) {
 			sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
-			result = acpi_sbs_generate_event(sbs->device,
-							 ACPI_SBS_BATTERY_NOTIFY_STATUS,
-							 new_battery_present,
+			result = acpi_bus_generate_event4(ACPI_BATTERY_CLASS,
 							 dir_name,
-							 ACPI_BATTERY_CLASS);
+							 ACPI_SBS_BATTERY_NOTIFY_STATUS,
+							 new_battery_present);
 			if (result) {
 				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-						"acpi_sbs_generate_event() "
+						"acpi_bus_generate_event4() "
 						"failed"));
 			}
 		}
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 3d0fea2..0878928 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -321,8 +321,9 @@ struct acpi_bus_event {
 };
 
 extern struct kset acpi_subsys;
-extern int acpi_bus_generate_genetlink_event(struct acpi_device *device,
-						u8 type, int data);
+extern int acpi_bus_generate_genetlink_event(const char *device_class,
+					     const char *bus_id,
+					     u8 type, int data);
 /*
  * External Functions
  */
@@ -333,6 +334,7 @@ int acpi_bus_get_status(struct acpi_device *device);
 int acpi_bus_get_power(acpi_handle handle, int *state);
 int acpi_bus_set_power(acpi_handle handle, int state);
 int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data);
+int acpi_bus_generate_event4(const char *class, const char *bid, u8 type, int data);
 int acpi_bus_receive_event(struct acpi_bus_event *event);
 int acpi_bus_register_driver(struct acpi_driver *driver);
 void acpi_bus_unregister_driver(struct acpi_driver *driver);


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

* [PATCH 07/12] ACPI: EC: Add new query handler to list head.
  2007-08-16 14:25 [PATCH 01/12] ACPI: AC: Add sysfs interface Alexey Starikovskiy
                   ` (4 preceding siblings ...)
  2007-08-16 14:26 ` [PATCH 06/12] ACPI: Add acpi_bus_generate_event4() function Alexey Starikovskiy
@ 2007-08-16 14:26 ` Alexey Starikovskiy
  2007-08-16 14:26 ` [PATCH 08/12] ACPI: SBS: Split host controller (ACPI0001) from SBS driver (ACPI0002) Alexey Starikovskiy
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Alexey Starikovskiy @ 2007-08-16 14:26 UTC (permalink / raw)
  To: lenb, linux-acpi; +Cc: astarikovskiy

From: Alexey Starikovskiy <astarikovskiy@suse.de>

Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
---

 drivers/acpi/ec.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 56bee9e..25a84af 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -425,7 +425,7 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
 	handler->func = func;
 	handler->data = data;
 	mutex_lock(&ec->lock);
-	list_add_tail(&handler->node, &ec->list);
+	list_add(&handler->node, &ec->list);
 	mutex_unlock(&ec->lock);
 	return 0;
 }
@@ -440,7 +440,6 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
 		if (query_bit == handler->query_bit) {
 			list_del(&handler->node);
 			kfree(handler);
-			break;
 		}
 	}
 	mutex_unlock(&ec->lock);


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

* [PATCH 08/12] ACPI: SBS: Split host controller (ACPI0001) from SBS driver (ACPI0002)
  2007-08-16 14:25 [PATCH 01/12] ACPI: AC: Add sysfs interface Alexey Starikovskiy
                   ` (5 preceding siblings ...)
  2007-08-16 14:26 ` [PATCH 07/12] ACPI: EC: Add new query handler to list head Alexey Starikovskiy
@ 2007-08-16 14:26 ` Alexey Starikovskiy
  2007-08-16 14:26 ` [PATCH 09/12] ACPI: SBS: Simplify data structures in SBS Alexey Starikovskiy
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Alexey Starikovskiy @ 2007-08-16 14:26 UTC (permalink / raw)
  To: lenb, linux-acpi; +Cc: astarikovskiy

From: Alexey Starikovskiy <astarikovskiy@suse.de>

Replace poll-based host controller driver with the notify-based one.
Split it out of sbs.c.
Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
---

 drivers/acpi/Makefile |    1 
 drivers/acpi/sbs.c    |  374 ++++++++++---------------------------------------
 drivers/acpi/sbshc.c  |  309 ++++++++++++++++++++++++++++++++++++++++
 drivers/acpi/sbshc.h  |   27 ++++
 4 files changed, 412 insertions(+), 299 deletions(-)

diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index d4336f1..54e3ab0 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -60,3 +60,4 @@ obj-$(CONFIG_ACPI_TOSHIBA)	+= toshiba_acpi.o
 obj-$(CONFIG_ACPI_HOTPLUG_MEMORY)	+= acpi_memhotplug.o
 obj-y				+= cm_sbs.o
 obj-$(CONFIG_ACPI_SBS)		+= sbs.o
+obj-$(CONFIG_ACPI_SBS)		+= sbshc.o
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 88af657..1c2365a 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -34,6 +34,8 @@
 #include <linux/jiffies.h>
 #include <linux/delay.h>
 
+#include "sbshc.h"
+
 #define ACPI_SBS_COMPONENT		0x00080000
 #define ACPI_SBS_CLASS			"sbs"
 #define ACPI_AC_CLASS			"ac_adapter"
@@ -59,28 +61,6 @@ MODULE_AUTHOR("Rich Townsend");
 MODULE_DESCRIPTION("Smart Battery System ACPI interface driver");
 MODULE_LICENSE("GPL");
 
-#define	xmsleep(t)	msleep(t)
-
-#define ACPI_EC_SMB_PRTCL	0x00	/* protocol, PEC */
-
-#define ACPI_EC_SMB_STS		0x01	/* status */
-#define ACPI_EC_SMB_ADDR	0x02	/* address */
-#define ACPI_EC_SMB_CMD		0x03	/* command */
-#define ACPI_EC_SMB_DATA	0x04	/* 32 data registers */
-#define ACPI_EC_SMB_BCNT	0x24	/* number of data bytes */
-
-#define ACPI_EC_SMB_STS_DONE	0x80
-#define ACPI_EC_SMB_STS_STATUS	0x1f
-
-#define ACPI_EC_SMB_PRTCL_WRITE		0x00
-#define ACPI_EC_SMB_PRTCL_READ		0x01
-#define ACPI_EC_SMB_PRTCL_WORD_DATA	0x08
-#define ACPI_EC_SMB_PRTCL_BLOCK_DATA	0x0a
-
-#define ACPI_EC_SMB_TRANSACTION_SLEEP	1
-#define ACPI_EC_SMB_ACCESS_SLEEP1	1
-#define ACPI_EC_SMB_ACCESS_SLEEP2	10
-
 #define	DEF_CAPACITY_UNIT	3
 #define	MAH_CAPACITY_UNIT	1
 #define	MWH_CAPACITY_UNIT	2
@@ -103,12 +83,6 @@ extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
 #define	MAX_SBS_BAT			4
 #define ACPI_SBS_BLOCK_MAX		32
 
-#define ACPI_SBS_SMBUS_READ		1
-#define ACPI_SBS_SMBUS_WRITE		2
-
-#define ACPI_SBS_WORD_DATA		1
-#define ACPI_SBS_BLOCK_DATA		2
-
 #define	UPDATE_DELAY	10
 
 /* 0 - every time, > 0 - by update_time */
@@ -124,8 +98,7 @@ static int acpi_sbs_remove(struct acpi_device *device, int type);
 static int acpi_sbs_resume(struct acpi_device *device);
 
 static const struct acpi_device_id sbs_device_ids[] = {
-	{"ACPI0001", 0},
-	{"ACPI0005", 0},
+	{"ACPI0002", 0},
 	{"", 0},
 };
 MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
@@ -182,8 +155,8 @@ struct acpi_battery {
 };
 
 struct acpi_sbs {
-	int base;
 	struct acpi_device *device;
+	struct acpi_smb_hc *hc;
 	struct mutex mutex;
 	int sbsm_present;
 	int sbsm_batteries_supported;
@@ -199,190 +172,6 @@ struct acpi_sbs {
 static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type);
 static void acpi_sbs_update_time(void *data);
 
-union sbs_rw_data {
-	u16 word;
-	u8 block[ACPI_SBS_BLOCK_MAX + 2];
-};
-
-static int acpi_ec_sbs_access(struct acpi_sbs *sbs, u16 addr,
-			      char read_write, u8 command, int size,
-			      union sbs_rw_data *data);
-
-/* --------------------------------------------------------------------------
-                               SMBus Communication
-   -------------------------------------------------------------------------- */
-
-static int acpi_ec_sbs_read(struct acpi_sbs *sbs, u8 address, u8 * data)
-{
-	u8 val;
-	int err;
-
-	err = ec_read(sbs->base + address, &val);
-	if (!err) {
-		*data = val;
-	}
-	xmsleep(ACPI_EC_SMB_TRANSACTION_SLEEP);
-	return (err);
-}
-
-static int acpi_ec_sbs_write(struct acpi_sbs *sbs, u8 address, u8 data)
-{
-	int err;
-
-	err = ec_write(sbs->base + address, data);
-	return (err);
-}
-
-static int
-acpi_ec_sbs_access(struct acpi_sbs *sbs, u16 addr,
-		   char read_write, u8 command, int size,
-		   union sbs_rw_data *data)
-{
-	unsigned char protocol, len = 0, temp[2] = { 0, 0 };
-	int i;
-
-	if (read_write == ACPI_SBS_SMBUS_READ) {
-		protocol = ACPI_EC_SMB_PRTCL_READ;
-	} else {
-		protocol = ACPI_EC_SMB_PRTCL_WRITE;
-	}
-
-	switch (size) {
-
-	case ACPI_SBS_WORD_DATA:
-		acpi_ec_sbs_write(sbs, ACPI_EC_SMB_CMD, command);
-		if (read_write == ACPI_SBS_SMBUS_WRITE) {
-			acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA, data->word);
-			acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA + 1,
-					  data->word >> 8);
-		}
-		protocol |= ACPI_EC_SMB_PRTCL_WORD_DATA;
-		break;
-	case ACPI_SBS_BLOCK_DATA:
-		acpi_ec_sbs_write(sbs, ACPI_EC_SMB_CMD, command);
-		if (read_write == ACPI_SBS_SMBUS_WRITE) {
-			len = min_t(u8, data->block[0], 32);
-			acpi_ec_sbs_write(sbs, ACPI_EC_SMB_BCNT, len);
-			for (i = 0; i < len; i++)
-				acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA + i,
-						  data->block[i + 1]);
-		}
-		protocol |= ACPI_EC_SMB_PRTCL_BLOCK_DATA;
-		break;
-	default:
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"unsupported transaction %d", size));
-		return (-1);
-	}
-
-	acpi_ec_sbs_write(sbs, ACPI_EC_SMB_ADDR, addr << 1);
-	acpi_ec_sbs_write(sbs, ACPI_EC_SMB_PRTCL, protocol);
-
-	acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp);
-
-	if (~temp[0] & ACPI_EC_SMB_STS_DONE) {
-		xmsleep(ACPI_EC_SMB_ACCESS_SLEEP1);
-		acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp);
-	}
-	if (~temp[0] & ACPI_EC_SMB_STS_DONE) {
-		xmsleep(ACPI_EC_SMB_ACCESS_SLEEP2);
-		acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp);
-	}
-	if ((~temp[0] & ACPI_EC_SMB_STS_DONE)
-	    || (temp[0] & ACPI_EC_SMB_STS_STATUS)) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"transaction %d error", size));
-		return (-1);
-	}
-
-	if (read_write == ACPI_SBS_SMBUS_WRITE) {
-		return (0);
-	}
-
-	switch (size) {
-
-	case ACPI_SBS_WORD_DATA:
-		acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA, temp);
-		acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA + 1, temp + 1);
-		data->word = (temp[1] << 8) | temp[0];
-		break;
-
-	case ACPI_SBS_BLOCK_DATA:
-		len = 0;
-		acpi_ec_sbs_read(sbs, ACPI_EC_SMB_BCNT, &len);
-		len = min_t(u8, len, 32);
-		for (i = 0; i < len; i++)
-			acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA + i,
-					 data->block + i + 1);
-		data->block[0] = len;
-		break;
-	default:
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"unsupported transaction %d", size));
-		return (-1);
-	}
-
-	return (0);
-}
-
-static int
-acpi_sbs_read_word(struct acpi_sbs *sbs, int addr, int func, u16 * word)
-{
-	union sbs_rw_data data;
-	int result = 0;
-
-	result = acpi_ec_sbs_access(sbs, addr,
-				    ACPI_SBS_SMBUS_READ, func,
-				    ACPI_SBS_WORD_DATA, &data);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_ec_sbs_access() failed"));
-	} else {
-		*word = data.word;
-	}
-
-	return result;
-}
-
-static int
-acpi_sbs_read_str(struct acpi_sbs *sbs, int addr, int func, char *str)
-{
-	union sbs_rw_data data;
-	int result = 0;
-
-	result = acpi_ec_sbs_access(sbs, addr,
-				    ACPI_SBS_SMBUS_READ, func,
-				    ACPI_SBS_BLOCK_DATA, &data);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_ec_sbs_access() failed"));
-	} else {
-		strncpy(str, (const char *)data.block + 1, data.block[0]);
-		str[data.block[0]] = 0;
-	}
-
-	return result;
-}
-
-static int
-acpi_sbs_write_word(struct acpi_sbs *sbs, int addr, int func, int word)
-{
-	union sbs_rw_data data;
-	int result = 0;
-
-	data.word = word;
-
-	result = acpi_ec_sbs_access(sbs, addr,
-				    ACPI_SBS_SMBUS_WRITE, func,
-				    ACPI_SBS_WORD_DATA, &data);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_ec_sbs_access() failed"));
-	}
-
-	return result;
-}
-
 static int sbs_zombie(struct acpi_sbs *sbs)
 {
 	return (sbs->zombie);
@@ -433,11 +222,11 @@ static int acpi_battery_get_present(struct acpi_battery *battery)
 	int result = 0;
 	int is_present = 0;
 
-	result = acpi_sbs_read_word(battery->sbs,
-				    ACPI_SBSM_SMBUS_ADDR, 0x01, &state);
+	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
+				    ACPI_SBSM_SMBUS_ADDR, 0x01, (u8 *)&state);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
+				"acpi_smbus_read() failed"));
 	}
 	if (!result) {
 		is_present = (state & 0x000f) & (1 << battery->id);
@@ -461,19 +250,19 @@ static int acpi_battery_select(struct acpi_battery *battery)
 		 * it causes charging to halt on SBSELs */
 
 		result =
-		    acpi_sbs_read_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x01, &state);
+		    acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SBSM_SMBUS_ADDR, 0x01, (u8 *)&state);
 		if (result) {
 			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_sbs_read_word() failed"));
+					"acpi_smbus_read() failed"));
 			goto end;
 		}
 
 		foo = (state & 0x0fff) | (1 << (battery->id + 12));
 		result =
-		    acpi_sbs_write_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x01, foo);
+		    acpi_smbus_write(battery->sbs->hc, SMBUS_WRITE_WORD, ACPI_SBSM_SMBUS_ADDR, 0x01, (u8 *)&foo, 2);
 		if (result) {
 			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_sbs_write_word() failed"));
+					"acpi_smbus_write() failed"));
 			goto end;
 		}
 	}
@@ -487,11 +276,11 @@ static int acpi_sbsm_get_info(struct acpi_sbs *sbs)
 	int result = 0;
 	s16 battery_system_info;
 
-	result = acpi_sbs_read_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x04,
-				    &battery_system_info);
+	result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBSM_SMBUS_ADDR, 0x04,
+				    (u8 *)&battery_system_info);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
+				"acpi_smbus_read() failed"));
 		goto end;
 	}
 	sbs->sbsm_present = 1;
@@ -504,50 +293,49 @@ static int acpi_sbsm_get_info(struct acpi_sbs *sbs)
 
 static int acpi_battery_get_info(struct acpi_battery *battery)
 {
-	struct acpi_sbs *sbs = battery->sbs;
 	int result = 0;
 	s16 battery_mode;
 	s16 specification_info;
 
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x03,
-				    &battery_mode);
+	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x03,
+				    (u8 *)&battery_mode);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
+				"acpi_smbus_read() failed"));
 		goto end;
 	}
 	battery->info.capacity_mode = (battery_mode & 0x8000) >> 15;
 
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x10,
-				    &battery->info.full_charge_capacity);
+	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x10,
+				    (u8 *)&battery->info.full_charge_capacity);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
+				"acpi_smbus_read() failed"));
 		goto end;
 	}
 
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x18,
-				    &battery->info.design_capacity);
+	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x18,
+				    (u8 *)&battery->info.design_capacity);
 
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
+				"acpi_smbus_read() failed"));
 		goto end;
 	}
 
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x19,
-				    &battery->info.design_voltage);
+	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x19,
+				    (u8 *)&battery->info.design_voltage);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
+				"acpi_smbus_read() failed"));
 		goto end;
 	}
 
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1a,
-				    &specification_info);
+	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x1a,
+				    (u8 *)&specification_info);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
+				"acpi_smbus_read() failed"));
 		goto end;
 	}
 
@@ -579,32 +367,32 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 		battery->info.ipscale = 1;
 	}
 
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1c,
-				    &battery->info.serial_number);
+	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x1c,
+				    (u8 *)&battery->info.serial_number);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
+				"acpi_smbus_read() failed"));
 		goto end;
 	}
 
-	result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x20,
-				   battery->info.manufacturer_name);
+	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_BLOCK, ACPI_SB_SMBUS_ADDR, 0x20,
+				   (u8 *)battery->info.manufacturer_name);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 				"acpi_sbs_read_str() failed"));
 		goto end;
 	}
 
-	result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x21,
-				   battery->info.device_name);
+	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_BLOCK, ACPI_SB_SMBUS_ADDR, 0x21,
+				   (u8 *)battery->info.device_name);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 				"acpi_sbs_read_str() failed"));
 		goto end;
 	}
 
-	result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x22,
-				   battery->info.device_chemistry);
+	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_BLOCK, ACPI_SB_SMBUS_ADDR, 0x22,
+				   (u8 *)battery->info.device_chemistry);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 				"acpi_sbs_read_str() failed"));
@@ -617,38 +405,37 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 
 static int acpi_battery_get_state(struct acpi_battery *battery)
 {
-	struct acpi_sbs *sbs = battery->sbs;
 	int result = 0;
 
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x09,
-				    &battery->state.voltage);
+	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x09,
+				    (u8 *)&battery->state.voltage);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
+				"acpi_smbus_read() failed"));
 		goto end;
 	}
 
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0a,
-				    &battery->state.amperage);
+	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x0a,
+				    (u8 *)&battery->state.amperage);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
+				"acpi_smbus_read() failed"));
 		goto end;
 	}
 
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0f,
-				    &battery->state.remaining_capacity);
+	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x0f,
+				    (u8 *)&battery->state.remaining_capacity);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
+				"acpi_smbus_read() failed"));
 		goto end;
 	}
 
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x16,
-				    &battery->state.battery_state);
+	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x16,
+				    (u8 *)&battery->state.battery_state);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
+				"acpi_smbus_read() failed"));
 		goto end;
 	}
 
@@ -658,14 +445,13 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 
 static int acpi_battery_get_alarm(struct acpi_battery *battery)
 {
-	struct acpi_sbs *sbs = battery->sbs;
 	int result = 0;
 
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01,
-				    &battery->alarm.remaining_capacity);
+	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x01,
+				    (u8 *)&battery->alarm.remaining_capacity);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
+				"acpi_smbus_read() failed"));
 		goto end;
 	}
 
@@ -677,7 +463,6 @@ static int acpi_battery_get_alarm(struct acpi_battery *battery)
 static int acpi_battery_set_alarm(struct acpi_battery *battery,
 				  unsigned long alarm)
 {
-	struct acpi_sbs *sbs = battery->sbs;
 	int result = 0;
 	s16 battery_mode;
 	int foo;
@@ -693,29 +478,30 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
 
 	if (alarm > 0) {
 		result =
-		    acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x03,
-				       &battery_mode);
+		    acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x03,
+				       (u8 *)&battery_mode);
 		if (result) {
 			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_sbs_read_word() failed"));
+					"acpi_smbus_read() failed"));
 			goto end;
 		}
 
+		battery_mode &= 0xbfff;
 		result =
-		    acpi_sbs_write_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01,
-					battery_mode & 0xbfff);
+		    acpi_smbus_write(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x01,
+					(u8 *)&battery_mode, 2);
 		if (result) {
 			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_sbs_write_word() failed"));
+					"acpi_smbus_write() failed"));
 			goto end;
 		}
 	}
 
 	foo = alarm / (battery->info.capacity_mode ? 10 : 1);
-	result = acpi_sbs_write_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01, foo);
+	result = acpi_smbus_write(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x01, (u8 *)&foo, 2);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_write_word() failed"));
+				"acpi_smbus_write() failed"));
 		goto end;
 	}
 
@@ -726,7 +512,6 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
 
 static int acpi_battery_set_mode(struct acpi_battery *battery)
 {
-	struct acpi_sbs *sbs = battery->sbs;
 	int result = 0;
 	s16 battery_mode;
 
@@ -734,11 +519,11 @@ static int acpi_battery_set_mode(struct acpi_battery *battery)
 		goto end;
 	}
 
-	result = acpi_sbs_read_word(sbs,
-				    ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode);
+	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
+				    ACPI_SB_SMBUS_ADDR, 0x03, (u8 *)&battery_mode);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
+				"acpi_smbus_read() failed"));
 		goto end;
 	}
 
@@ -747,19 +532,19 @@ static int acpi_battery_set_mode(struct acpi_battery *battery)
 	} else {
 		battery_mode |= 0x8000;
 	}
-	result = acpi_sbs_write_word(sbs,
-				     ACPI_SB_SMBUS_ADDR, 0x03, battery_mode);
+	result = acpi_smbus_write(battery->sbs->hc, SMBUS_READ_WORD,
+				     ACPI_SB_SMBUS_ADDR, 0x03, (u8 *)&battery_mode, 2);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_write_word() failed"));
+				"acpi_smbus_write() failed"));
 		goto end;
 	}
 
-	result = acpi_sbs_read_word(sbs,
-				    ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode);
+	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
+				    ACPI_SB_SMBUS_ADDR, 0x03, (u8 *)&battery_mode);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
+				"acpi_smbus_read() failed"));
 		goto end;
 	}
 
@@ -815,12 +600,12 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)
 	int result = 0;
 	s16 charger_status;
 
-	result = acpi_sbs_read_word(sbs, ACPI_SBC_SMBUS_ADDR, 0x13,
-				    &charger_status);
+	result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBC_SMBUS_ADDR, 0x13,
+				    (u8 *)&charger_status);
 
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
+				"acpi_smbus_read() failed"));
 		goto end;
 	}
 
@@ -1608,15 +1393,6 @@ static int acpi_sbs_add(struct acpi_device *device)
 	struct acpi_sbs *sbs = NULL;
 	int result = 0, remove_result = 0;
 	int id;
-	acpi_status status = AE_OK;
-	unsigned long val;
-
-	status =
-	    acpi_evaluate_integer(device->handle, "_EC", NULL, &val);
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Error obtaining _EC"));
-		return -EIO;
-	}
 
 	sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL);
 	if (!sbs) {
@@ -1629,8 +1405,8 @@ static int acpi_sbs_add(struct acpi_device *device)
 
 	sbs_mutex_lock(sbs);
 
-	sbs->base = 0xff & (val >> 8);
 	sbs->device = device;
+	sbs->hc = acpi_driver_data(device->parent);
 
 	strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_SBS_CLASS);
diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c
new file mode 100644
index 0000000..046d7c3
--- /dev/null
+++ b/drivers/acpi/sbshc.c
@@ -0,0 +1,309 @@
+/*
+ * SMBus driver for ACPI Embedded Controller (v0.1)
+ *
+ * Copyright (c) 2007 Alexey Starikovskiy
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2.
+ */
+
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/actypes.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include "sbshc.h"
+
+#define ACPI_SMB_HC_CLASS	"smbus_host_controller"
+#define ACPI_SMB_HC_DEVICE_NAME	"ACPI SMBus HC"
+
+struct acpi_smb_hc {
+	struct acpi_ec *ec;
+	struct mutex lock;
+	wait_queue_head_t wait;
+	u8 offset;
+	u8 query_bit;
+	smbus_alarm_callback callback;
+	void *context;
+};
+
+static int acpi_smbus_hc_add(struct acpi_device *device);
+static int acpi_smbus_hc_remove(struct acpi_device *device, int type);
+
+static const struct acpi_device_id sbs_device_ids[] = {
+	{"ACPI0001", 0},
+	{"ACPI0005", 0},
+	{"", 0},
+};
+
+MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
+
+static struct acpi_driver acpi_smb_hc_driver = {
+	.name = "smbus_hc",
+	.class = ACPI_SMB_HC_CLASS,
+	.ids = sbs_device_ids,
+	.ops = {
+		.add = acpi_smbus_hc_add,
+		.remove = acpi_smbus_hc_remove,
+		},
+};
+
+union acpi_smb_status {
+	u8 raw;
+	struct {
+		u8 status:5;
+		u8 reserved:1;
+		u8 alarm:1;
+		u8 done:1;
+	} fields;
+};
+
+enum acpi_smb_status_codes {
+	SMBUS_OK = 0,
+	SMBUS_UNKNOWN_FAILURE = 0x07,
+	SMBUS_DEVICE_ADDRESS_NACK = 0x10,
+	SMBUS_DEVICE_ERROR = 0x11,
+	SMBUS_DEVICE_COMMAND_ACCESS_DENIED = 0x12,
+	SMBUS_UNKNOWN_ERROR = 0x13,
+	SMBUS_DEVICE_ACCESS_DENIED = 0x17,
+	SMBUS_TIMEOUT = 0x18,
+	SMBUS_HOST_UNSUPPORTED_PROTOCOL = 0x19,
+	SMBUS_BUSY = 0x1a,
+	SMBUS_PEC_ERROR = 0x1f,
+};
+
+enum acpi_smb_offset {
+	ACPI_SMB_PROTOCOL = 0,	/* protocol, PEC */
+	ACPI_SMB_STATUS = 1,	/* status */
+	ACPI_SMB_ADDRESS = 2,	/* address */
+	ACPI_SMB_COMMAND = 3,	/* command */
+	ACPI_SMB_DATA = 4,	/* 32 data registers */
+	ACPI_SMB_BLOCK_COUNT = 0x24,	/* number of data bytes */
+	ACPI_SMB_ALARM_ADDRESS = 0x25,	/* alarm address */
+	ACPI_SMB_ALARM_DATA = 0x26,	/* 2 bytes alarm data */
+};
+
+static inline int smb_hc_read(struct acpi_smb_hc *hc, u8 address, u8 *data)
+{
+	return ec_read(hc->offset + address, data);
+}
+
+static inline int smb_hc_write(struct acpi_smb_hc *hc, u8 address, u8 data)
+{
+	return ec_write(hc->offset + address, data);
+}
+
+static inline int smb_check_done(struct acpi_smb_hc *hc)
+{
+	union acpi_smb_status status = {.raw = 0};
+	smb_hc_read(hc, ACPI_SMB_STATUS, &status.raw);
+	return status.fields.done && (status.fields.status == SMBUS_OK);
+}
+
+static int wait_transaction_complete(struct acpi_smb_hc *hc, int timeout)
+{
+	if (wait_event_timeout(hc->wait, smb_check_done(hc),
+			       msecs_to_jiffies(timeout)))
+		return 0;
+	else
+		return -ETIME;
+}
+
+int acpi_smbus_transaction(struct acpi_smb_hc *hc, u8 protocol, u8 address,
+		    u8 command, u8 *data, u8 length)
+{
+	int ret = -EFAULT, i;
+	u8 temp, sz = 0;
+
+	mutex_lock(&hc->lock);
+	if (smb_hc_read(hc, ACPI_SMB_PROTOCOL, &temp))
+		goto end;
+	if (temp) {
+		ret = -EBUSY;
+		goto end;
+	}
+	smb_hc_write(hc, ACPI_SMB_COMMAND, command);
+	smb_hc_write(hc, ACPI_SMB_COMMAND, command);
+	if (!(protocol & 0x01)) {
+		smb_hc_write(hc, ACPI_SMB_BLOCK_COUNT, length);
+		for (i = 0; i < length; ++i)
+			smb_hc_write(hc, ACPI_SMB_DATA + i, data[i]);
+	}
+	smb_hc_write(hc, ACPI_SMB_ADDRESS, address << 1);
+	smb_hc_write(hc, ACPI_SMB_PROTOCOL, protocol);
+	/*
+	 * Wait for completion. Save the status code, data size,
+	 * and data into the return package (if required by the protocol).
+	 */
+	ret = wait_transaction_complete(hc, 1000);
+	if (ret || !(protocol & 0x01))
+		goto end;
+	switch (protocol) {
+	case SMBUS_RECEIVE_BYTE:
+	case SMBUS_READ_BYTE:
+		sz = 1;
+		break;
+	case SMBUS_READ_WORD:
+		sz = 2;
+		break;
+	case SMBUS_READ_BLOCK:
+		if (smb_hc_read(hc, ACPI_SMB_BLOCK_COUNT, &sz)) {
+			ret = -EFAULT;
+			goto end;
+		}
+		sz &= 0x1f;
+		break;
+	}
+	for (i = 0; i < sz; ++i)
+		smb_hc_read(hc, ACPI_SMB_DATA + i, &data[i]);
+      end:
+	mutex_unlock(&hc->lock);
+	return ret;
+}
+
+int acpi_smbus_read(struct acpi_smb_hc *hc, u8 protocol, u8 address,
+		    u8 command, u8 *data)
+{
+	return acpi_smbus_transaction(hc, protocol, address, command, data, 0);
+}
+
+EXPORT_SYMBOL_GPL(acpi_smbus_read);
+
+int acpi_smbus_write(struct acpi_smb_hc *hc, u8 protocol, u8 address,
+		     u8 command, u8 *data, u8 length)
+{
+	return acpi_smbus_transaction(hc, protocol, address, command, data, length);
+}
+
+EXPORT_SYMBOL_GPL(acpi_smbus_write);
+
+int acpi_smbus_register_callback(struct acpi_smb_hc *hc,
+			         smbus_alarm_callback callback, void *context)
+{
+	mutex_lock(&hc->lock);
+	hc->callback = callback;
+	hc->context = context;
+	mutex_unlock(&hc->lock);
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(acpi_smbus_register_callback);
+
+int acpi_smbus_unregister_callback(struct acpi_smb_hc *hc)
+{
+	mutex_lock(&hc->lock);
+	hc->callback = NULL;
+	hc->context = NULL;
+	mutex_unlock(&hc->lock);
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(acpi_smbus_unregister_callback);
+
+static void acpi_smbus_callback(void *context)
+{
+	struct acpi_smb_hc *hc = context;
+
+	if (hc->callback)
+		hc->callback(hc->context);
+}
+
+static int smbus_alarm(void *context)
+{
+	struct acpi_smb_hc *hc = context;
+	union acpi_smb_status status;
+	if (smb_hc_read(hc, ACPI_SMB_STATUS, &status.raw))
+		return 0;
+	/* Check if it is only a completion notify */
+	if (status.fields.done)
+		wake_up(&hc->wait);
+	if (!status.fields.alarm)
+		return 0;
+	mutex_lock(&hc->lock);
+	smb_hc_write(hc, ACPI_SMB_STATUS, status.raw);
+	if (hc->callback)
+		acpi_os_execute(OSL_GPE_HANDLER, acpi_smbus_callback, hc);
+	mutex_unlock(&hc->lock);
+	return 0;
+}
+
+typedef int (*acpi_ec_query_func) (void *data);
+
+extern int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
+			      acpi_handle handle, acpi_ec_query_func func,
+			      void *data);
+
+static int acpi_smbus_hc_add(struct acpi_device *device)
+{
+	int status;
+	unsigned long val;
+	struct acpi_smb_hc *hc;
+
+	if (!device)
+		return -EINVAL;
+
+	status = acpi_evaluate_integer(device->handle, "_EC", NULL, &val);
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_ERR PREFIX "error obtaining _EC.\n");
+		return -EIO;
+	}
+
+	strcpy(acpi_device_name(device), ACPI_SMB_HC_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_SMB_HC_CLASS);
+
+	hc = kzalloc(sizeof(struct acpi_smb_hc), GFP_KERNEL);
+	if (!hc)
+		return -ENOMEM;
+	mutex_init(&hc->lock);
+	init_waitqueue_head(&hc->wait);
+
+	hc->ec = acpi_driver_data(device->parent);
+	hc->offset = (val >> 8) & 0xff;
+	hc->query_bit = val & 0xff;
+	acpi_driver_data(device) = hc;
+
+	acpi_ec_add_query_handler(hc->ec, hc->query_bit, NULL, smbus_alarm, hc);
+	printk(KERN_INFO PREFIX "SBS HC: EC = 0x%p, offset = 0x%0x, query_bit = 0x%0x\n",
+		hc->ec, hc->offset, hc->query_bit);
+
+	return 0;
+}
+
+extern void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit);
+
+static int acpi_smbus_hc_remove(struct acpi_device *device, int type)
+{
+	struct acpi_smb_hc *hc;
+
+	if (!device)
+		return -EINVAL;
+
+	hc = acpi_driver_data(device);
+	acpi_ec_remove_query_handler(hc->ec, hc->query_bit);
+	kfree(hc);
+	return 0;
+}
+
+static int __init acpi_smb_hc_init(void)
+{
+	int result;
+
+	result = acpi_bus_register_driver(&acpi_smb_hc_driver);
+	if (result < 0)
+		return -ENODEV;
+	return 0;
+}
+
+static void __exit acpi_smb_hc_exit(void)
+{
+	acpi_bus_unregister_driver(&acpi_smb_hc_driver);
+}
+
+module_init(acpi_smb_hc_init);
+module_exit(acpi_smb_hc_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alexey Starikovskiy");
+MODULE_DESCRIPTION("ACPI SMBus HC driver");
diff --git a/drivers/acpi/sbshc.h b/drivers/acpi/sbshc.h
new file mode 100644
index 0000000..3bda349
--- /dev/null
+++ b/drivers/acpi/sbshc.h
@@ -0,0 +1,27 @@
+struct acpi_smb_hc;
+enum acpi_smb_protocol {
+	SMBUS_WRITE_QUICK = 2,
+	SMBUS_READ_QUICK = 3,
+	SMBUS_SEND_BYTE = 4,
+	SMBUS_RECEIVE_BYTE = 5,
+	SMBUS_WRITE_BYTE = 6,
+	SMBUS_READ_BYTE = 7,
+	SMBUS_WRITE_WORD  = 8,
+	SMBUS_READ_WORD  = 9,
+	SMBUS_WRITE_BLOCK = 0xa,
+	SMBUS_READ_BLOCK = 0xb,
+	SMBUS_PROCESS_CALL = 0xc,
+	SMBUS_BLOCK_PROCESS_CALL = 0xd,
+};
+
+static const u8 SMBUS_PEC = 0x80;
+
+typedef void (*smbus_alarm_callback)(void *context);
+
+extern int acpi_smbus_read(struct acpi_smb_hc *hc, u8 protocol, u8 address,
+	       u8 command, u8 * data);
+extern int acpi_smbus_write(struct acpi_smb_hc *hc, u8 protocol, u8 slave_address,
+		u8 command, u8 * data, u8 length);
+extern int acpi_smbus_register_callback(struct acpi_smb_hc *hc,
+			         smbus_alarm_callback callback, void *context);
+extern int acpi_smbus_unregister_callback(struct acpi_smb_hc *hc);


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

* [PATCH 09/12] ACPI: SBS: Simplify data structures in SBS
  2007-08-16 14:25 [PATCH 01/12] ACPI: AC: Add sysfs interface Alexey Starikovskiy
                   ` (6 preceding siblings ...)
  2007-08-16 14:26 ` [PATCH 08/12] ACPI: SBS: Split host controller (ACPI0001) from SBS driver (ACPI0002) Alexey Starikovskiy
@ 2007-08-16 14:26 ` Alexey Starikovskiy
  2007-08-16 14:26 ` [PATCH 10/12] ACPI: SBS: Make SBS reads table-driven Alexey Starikovskiy
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Alexey Starikovskiy @ 2007-08-16 14:26 UTC (permalink / raw)
  To: lenb, linux-acpi; +Cc: astarikovskiy

From: Alexey Starikovskiy <astarikovskiy@suse.de>

Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
---

 drivers/acpi/sbs.c |  280 +++++++++++++++++++++++++---------------------------
 1 files changed, 134 insertions(+), 146 deletions(-)

diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 1c2365a..4aee7fb 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -88,10 +88,10 @@ extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
 /* 0 - every time, > 0 - by update_time */
 static unsigned int update_time = 120;
 
-static unsigned int capacity_mode = CAPACITY_UNIT;
+static unsigned int mode = CAPACITY_UNIT;
 
 module_param(update_time, uint, 0644);
-module_param(capacity_mode, uint, 0444);
+module_param(mode, uint, 0444);
 
 static int acpi_sbs_add(struct acpi_device *device);
 static int acpi_sbs_remove(struct acpi_device *device, int type);
@@ -114,59 +114,43 @@ static struct acpi_driver acpi_sbs_driver = {
 		},
 };
 
-struct acpi_ac {
-	int ac_present;
-};
-
-struct acpi_battery_info {
-	int capacity_mode;
-	s16 full_charge_capacity;
-	s16 design_capacity;
-	s16 design_voltage;
-	int vscale;
-	int ipscale;
-	s16 serial_number;
-	char manufacturer_name[ACPI_SBS_BLOCK_MAX + 3];
-	char device_name[ACPI_SBS_BLOCK_MAX + 3];
-	char device_chemistry[ACPI_SBS_BLOCK_MAX + 3];
-};
-
-struct acpi_battery_state {
-	s16 voltage;
-	s16 amperage;
-	s16 remaining_capacity;
-	s16 battery_state;
-};
-
-struct acpi_battery_alarm {
-	s16 remaining_capacity;
-};
-
 struct acpi_battery {
-	int alive;
-	int id;
-	int init_state;
-	int battery_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 proc_dir_entry *proc_entry;
+	int vscale;
+	int ipscale;
+	char manufacturer_name[ACPI_SBS_BLOCK_MAX];
+	char device_name[ACPI_SBS_BLOCK_MAX];
+	char device_chemistry[ACPI_SBS_BLOCK_MAX];
+	u16 full_charge_capacity;
+	u16 design_capacity;
+	u16 design_voltage;
+	u16 serial_number;
+	u16 voltage_now;
+	s16 current_now;
+	u16 capacity_now;
+	u16 state;
+	u16 alarm_capacity;
+	u16 mode;
+	u8 id;
+	u8 alive:1;
+	u8 init_state:1;
+	u8 present:1;
 };
 
 struct acpi_sbs {
 	struct acpi_device *device;
 	struct acpi_smb_hc *hc;
 	struct mutex mutex;
-	int sbsm_present;
-	int sbsm_batteries_supported;
 	struct proc_dir_entry *ac_entry;
-	struct acpi_ac ac;
 	struct acpi_battery battery[MAX_SBS_BAT];
 	int zombie;
 	struct timer_list update_timer;
 	int run_cnt;
 	int update_proc_flg;
+	u8 batteries_supported;
+	u8 manager_present:1;
+	u8 charger_present:1;
 };
 
 static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type);
@@ -231,7 +215,7 @@ static int acpi_battery_get_present(struct acpi_battery *battery)
 	if (!result) {
 		is_present = (state & 0x000f) & (1 << battery->id);
 	}
-	battery->battery_present = is_present;
+	battery->present = is_present;
 
 	return result;
 }
@@ -243,14 +227,14 @@ static int acpi_battery_select(struct acpi_battery *battery)
 	s16 state;
 	int foo;
 
-	if (sbs->sbsm_present) {
+	if (sbs->manager_present) {
 
 		/* Take special care not to knobble other nibbles of
 		 * state (aka selector_state), since
 		 * it causes charging to halt on SBSELs */
 
-		result =
-		    acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SBSM_SMBUS_ADDR, 0x01, (u8 *)&state);
+		result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
+					 ACPI_SBSM_SMBUS_ADDR, 0x01, (u8 *)&state);
 		if (result) {
 			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 					"acpi_smbus_read() failed"));
@@ -258,8 +242,8 @@ static int acpi_battery_select(struct acpi_battery *battery)
 		}
 
 		foo = (state & 0x0fff) | (1 << (battery->id + 12));
-		result =
-		    acpi_smbus_write(battery->sbs->hc, SMBUS_WRITE_WORD, ACPI_SBSM_SMBUS_ADDR, 0x01, (u8 *)&foo, 2);
+		result = acpi_smbus_write(battery->sbs->hc, SMBUS_WRITE_WORD,
+					  ACPI_SBSM_SMBUS_ADDR, 0x01, (u8 *)&foo, 2);
 		if (result) {
 			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 					"acpi_smbus_write() failed"));
@@ -283,8 +267,7 @@ static int acpi_sbsm_get_info(struct acpi_sbs *sbs)
 				"acpi_smbus_read() failed"));
 		goto end;
 	}
-	sbs->sbsm_present = 1;
-	sbs->sbsm_batteries_supported = battery_system_info & 0x000f;
+	sbs->manager_present = 1;
 
       end:
 
@@ -304,10 +287,10 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 				"acpi_smbus_read() failed"));
 		goto end;
 	}
-	battery->info.capacity_mode = (battery_mode & 0x8000) >> 15;
+	battery->mode = (battery_mode & 0x8000) >> 15;
 
 	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x10,
-				    (u8 *)&battery->info.full_charge_capacity);
+				    (u8 *)&battery->full_charge_capacity);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 				"acpi_smbus_read() failed"));
@@ -315,7 +298,7 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 	}
 
 	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x18,
-				    (u8 *)&battery->info.design_capacity);
+				    (u8 *)&battery->design_capacity);
 
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -324,7 +307,7 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 	}
 
 	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x19,
-				    (u8 *)&battery->info.design_voltage);
+				    (u8 *)&battery->design_voltage);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 				"acpi_smbus_read() failed"));
@@ -341,34 +324,34 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 
 	switch ((specification_info & 0x0f00) >> 8) {
 	case 1:
-		battery->info.vscale = 10;
+		battery->vscale = 10;
 		break;
 	case 2:
-		battery->info.vscale = 100;
+		battery->vscale = 100;
 		break;
 	case 3:
-		battery->info.vscale = 1000;
+		battery->vscale = 1000;
 		break;
 	default:
-		battery->info.vscale = 1;
+		battery->vscale = 1;
 	}
 
 	switch ((specification_info & 0xf000) >> 12) {
 	case 1:
-		battery->info.ipscale = 10;
+		battery->ipscale = 10;
 		break;
 	case 2:
-		battery->info.ipscale = 100;
+		battery->ipscale = 100;
 		break;
 	case 3:
-		battery->info.ipscale = 1000;
+		battery->ipscale = 1000;
 		break;
 	default:
-		battery->info.ipscale = 1;
+		battery->ipscale = 1;
 	}
 
 	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x1c,
-				    (u8 *)&battery->info.serial_number);
+				    (u8 *)&battery->serial_number);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 				"acpi_smbus_read() failed"));
@@ -376,7 +359,7 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 	}
 
 	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_BLOCK, ACPI_SB_SMBUS_ADDR, 0x20,
-				   (u8 *)battery->info.manufacturer_name);
+				   (u8 *)battery->manufacturer_name);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 				"acpi_sbs_read_str() failed"));
@@ -384,7 +367,7 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 	}
 
 	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_BLOCK, ACPI_SB_SMBUS_ADDR, 0x21,
-				   (u8 *)battery->info.device_name);
+				   (u8 *)battery->device_name);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 				"acpi_sbs_read_str() failed"));
@@ -392,7 +375,7 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 	}
 
 	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_BLOCK, ACPI_SB_SMBUS_ADDR, 0x22,
-				   (u8 *)battery->info.device_chemistry);
+				   (u8 *)battery->device_chemistry);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 				"acpi_sbs_read_str() failed"));
@@ -408,7 +391,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 	int result = 0;
 
 	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x09,
-				    (u8 *)&battery->state.voltage);
+				    (u8 *)&battery->voltage_now);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 				"acpi_smbus_read() failed"));
@@ -416,7 +399,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 	}
 
 	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x0a,
-				    (u8 *)&battery->state.amperage);
+				    (u8 *)&battery->current_now);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 				"acpi_smbus_read() failed"));
@@ -424,7 +407,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 	}
 
 	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x0f,
-				    (u8 *)&battery->state.remaining_capacity);
+				    (u8 *)&battery->capacity_now);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 				"acpi_smbus_read() failed"));
@@ -432,7 +415,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 	}
 
 	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x16,
-				    (u8 *)&battery->state.battery_state);
+				    (u8 *)&battery->state);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 				"acpi_smbus_read() failed"));
@@ -448,7 +431,7 @@ static int acpi_battery_get_alarm(struct acpi_battery *battery)
 	int result = 0;
 
 	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x01,
-				    (u8 *)&battery->alarm.remaining_capacity);
+				    (u8 *)&battery->alarm_capacity);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 				"acpi_smbus_read() failed"));
@@ -497,8 +480,9 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
 		}
 	}
 
-	foo = alarm / (battery->info.capacity_mode ? 10 : 1);
-	result = acpi_smbus_write(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x01, (u8 *)&foo, 2);
+	foo = alarm / (battery->mode ? 10 : 1);
+	result = acpi_smbus_write(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x01,
+				  (u8 *)&foo, 2);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 				"acpi_smbus_write() failed"));
@@ -515,25 +499,25 @@ static int acpi_battery_set_mode(struct acpi_battery *battery)
 	int result = 0;
 	s16 battery_mode;
 
-	if (capacity_mode == DEF_CAPACITY_UNIT) {
+	if (mode == DEF_CAPACITY_UNIT) {
 		goto end;
 	}
 
 	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
-				    ACPI_SB_SMBUS_ADDR, 0x03, (u8 *)&battery_mode);
+				 ACPI_SB_SMBUS_ADDR, 0x03, (u8 *)&battery_mode);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 				"acpi_smbus_read() failed"));
 		goto end;
 	}
 
-	if (capacity_mode == MAH_CAPACITY_UNIT) {
+	if (mode == MAH_CAPACITY_UNIT) {
 		battery_mode &= 0x7fff;
 	} else {
 		battery_mode |= 0x8000;
 	}
 	result = acpi_smbus_write(battery->sbs->hc, SMBUS_READ_WORD,
-				     ACPI_SB_SMBUS_ADDR, 0x03, (u8 *)&battery_mode, 2);
+				  ACPI_SB_SMBUS_ADDR, 0x03, (u8 *)&battery_mode, 2);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 				"acpi_smbus_write() failed"));
@@ -541,7 +525,7 @@ static int acpi_battery_set_mode(struct acpi_battery *battery)
 	}
 
 	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
-				    ACPI_SB_SMBUS_ADDR, 0x03, (u8 *)&battery_mode);
+				 ACPI_SB_SMBUS_ADDR, 0x03, (u8 *)&battery_mode);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 				"acpi_smbus_read() failed"));
@@ -601,7 +585,7 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)
 	s16 charger_status;
 
 	result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBC_SMBUS_ADDR, 0x13,
-				    (u8 *)&charger_status);
+				 (u8 *)&charger_status);
 
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -609,7 +593,7 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)
 		goto end;
 	}
 
-	sbs->ac.ac_present = (charger_status & 0x8000) >> 15;
+	sbs->charger_present = (charger_status & 0x8000) >> 15;
 
       end:
 
@@ -726,30 +710,30 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
 		}
 	}
 
-	if (battery->battery_present) {
+	if (battery->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 (battery->mode) {
+		cscale = battery->vscale * battery->ipscale;
 	} else {
-		cscale = battery->info.ipscale;
+		cscale = battery->ipscale;
 	}
 	seq_printf(seq, "design capacity:         %i%s\n",
-		   battery->info.design_capacity * cscale,
-		   battery->info.capacity_mode ? "0 mWh" : " mAh");
+		   battery->design_capacity * cscale,
+		   battery->mode ? "0 mWh" : " mAh");
 
 	seq_printf(seq, "last full capacity:      %i%s\n",
-		   battery->info.full_charge_capacity * cscale,
-		   battery->info.capacity_mode ? "0 mWh" : " mAh");
+		   battery->full_charge_capacity * cscale,
+		   battery->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);
+		   battery->design_voltage * battery->vscale);
 
 	seq_printf(seq, "design capacity warning: unknown\n");
 	seq_printf(seq, "design capacity low:     unknown\n");
@@ -757,16 +741,16 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
 	seq_printf(seq, "capacity granularity 2:  unknown\n");
 
 	seq_printf(seq, "model number:            %s\n",
-		   battery->info.device_name);
+		   battery->device_name);
 
 	seq_printf(seq, "serial number:           %i\n",
-		   battery->info.serial_number);
+		   battery->serial_number);
 
 	seq_printf(seq, "battery type:            %s\n",
-		   battery->info.device_chemistry);
+		   battery->device_chemistry);
 
 	seq_printf(seq, "OEM info:                %s\n",
-		   battery->info.manufacturer_name);
+		   battery->manufacturer_name);
 
       end:
 
@@ -804,49 +788,49 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
 		}
 	}
 
-	if (battery->battery_present) {
+	if (battery->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 (battery->mode) {
+		cscale = battery->vscale * battery->ipscale;
 	} else {
-		cscale = battery->info.ipscale;
+		cscale = battery->ipscale;
 	}
 
-	if (battery->state.battery_state & 0x0010) {
+	if (battery->state & 0x0010) {
 		seq_printf(seq, "capacity state:          critical\n");
 	} else {
 		seq_printf(seq, "capacity state:          ok\n");
 	}
 
-	foo = (s16) battery->state.amperage * battery->info.ipscale;
-	if (battery->info.capacity_mode) {
-		foo = foo * battery->info.design_voltage / 1000;
+	foo = (s16) battery->current_now * battery->ipscale;
+	if (battery->mode) {
+		foo = foo * battery->design_voltage / 1000;
 	}
-	if (battery->state.amperage < 0) {
+	if (battery->current_now < 0) {
 		seq_printf(seq, "charging state:          discharging\n");
 		seq_printf(seq, "present rate:            %d %s\n",
-			   -foo, battery->info.capacity_mode ? "mW" : "mA");
-	} else if (battery->state.amperage > 0) {
+			   -foo, battery->mode ? "mW" : "mA");
+	} else if (battery->current_now > 0) {
 		seq_printf(seq, "charging state:          charging\n");
 		seq_printf(seq, "present rate:            %d %s\n",
-			   foo, battery->info.capacity_mode ? "mW" : "mA");
+			   foo, battery->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");
+			   battery->mode ? "mW" : "mA");
 	}
 
 	seq_printf(seq, "remaining capacity:      %i%s\n",
-		   battery->state.remaining_capacity * cscale,
-		   battery->info.capacity_mode ? "0 mWh" : " mAh");
+		   battery->capacity_now * cscale,
+		   battery->mode ? "0 mWh" : " mAh");
 
 	seq_printf(seq, "present voltage:         %i mV\n",
-		   battery->state.voltage * battery->info.vscale);
+		   battery->voltage_now * battery->vscale);
 
       end:
 
@@ -883,22 +867,22 @@ static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
 		}
 	}
 
-	if (!battery->battery_present) {
+	if (!battery->present) {
 		seq_printf(seq, "present:                 no\n");
 		goto end;
 	}
 
-	if (battery->info.capacity_mode) {
-		cscale = battery->info.vscale * battery->info.ipscale;
+	if (battery->mode) {
+		cscale = battery->vscale * battery->ipscale;
 	} else {
-		cscale = battery->info.ipscale;
+		cscale = battery->ipscale;
 	}
 
 	seq_printf(seq, "alarm:                   ");
-	if (battery->alarm.remaining_capacity) {
+	if (battery->alarm_capacity) {
 		seq_printf(seq, "%i%s\n",
-			   battery->alarm.remaining_capacity * cscale,
-			   battery->info.capacity_mode ? "0 mWh" : " mAh");
+			   battery->alarm_capacity * cscale,
+			   battery->mode ? "0 mWh" : " mAh");
 	} else {
 		seq_printf(seq, "disabled\n");
 	}
@@ -928,7 +912,7 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer,
 	if (result)
 		goto end;
 
-	if (!battery->battery_present) {
+	if (!battery->present) {
 		result = -ENODEV;
 		goto end;
 	}
@@ -945,7 +929,7 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer,
 
 	alarm_string[count] = 0;
 
-	old_alarm = battery->alarm.remaining_capacity;
+	old_alarm = battery->alarm_capacity;
 	new_alarm = simple_strtoul(alarm_string, NULL, 0);
 
 	result = acpi_battery_set_alarm(battery, new_alarm);
@@ -1025,7 +1009,7 @@ static int acpi_ac_read_state(struct seq_file *seq, void *offset)
 	}
 
 	seq_printf(seq, "state:                   %s\n",
-		   sbs->ac.ac_present ? "on-line" : "off-line");
+		   sbs->charger_present ? "on-line" : "off-line");
 
 	sbs_mutex_unlock(sbs);
 
@@ -1080,7 +1064,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
 		goto end;
 	}
 
-	is_present = battery->battery_present;
+	is_present = battery->present;
 
 	if (is_present) {
 		result = acpi_battery_init(battery);
@@ -1094,7 +1078,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
 
 	sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
 
-	result = acpi_sbs_generic_add_fs(&battery->battery_entry,
+	result = acpi_sbs_generic_add_fs(&battery->proc_entry,
 					 acpi_battery_dir,
 					 dir_name,
 					 &acpi_battery_info_fops,
@@ -1109,7 +1093,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
 
 	printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",
 	       ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), dir_name,
-	       sbs->battery->battery_present ? "present" : "absent");
+	       sbs->battery->present ? "present" : "absent");
 
       end:
 	return result;
@@ -1118,8 +1102,8 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
 static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
 {
 
-	if (sbs->battery[id].battery_entry) {
-		acpi_sbs_generic_remove_fs(&(sbs->battery[id].battery_entry),
+	if (sbs->battery[id].proc_entry) {
+		acpi_sbs_generic_remove_fs(&(sbs->battery[id].proc_entry),
 					   acpi_battery_dir);
 	}
 }
@@ -1147,7 +1131,7 @@ static int acpi_ac_add(struct acpi_sbs *sbs)
 
 	printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",
 	       ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
-	       ACPI_AC_DIR_NAME, sbs->ac.ac_present ? "on-line" : "off-line");
+	       ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line");
 
       end:
 
@@ -1172,9 +1156,9 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)
 	struct acpi_battery *battery;
 	int result = 0, cnt;
 	int old_ac_present = -1;
-	int old_battery_present = -1;
+	int old_present = -1;
 	int new_ac_present = -1;
-	int new_battery_present = -1;
+	int new_present = -1;
 	int id_min = 0, id_max = MAX_SBS_BAT - 1;
 	char dir_name[32];
 	int do_battery_init = 0, do_ac_init = 0;
@@ -1199,7 +1183,11 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)
 
 	sbs->run_cnt++;
 
-	old_ac_present = sbs->ac.ac_present;
+	if (!update_battery) {
+		goto end;
+	}
+
+	old_ac_present = sbs->charger_present;
 
 	result = acpi_ac_get_present(sbs);
 	if (result) {
@@ -1207,7 +1195,7 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)
 				"acpi_ac_get_present() failed"));
 	}
 
-	new_ac_present = sbs->ac.ac_present;
+	new_ac_present = sbs->charger_present;
 
 	do_ac_init = (old_ac_present != new_ac_present);
 	if (sbs->run_cnt == 1 && data_type == DATA_TYPE_COMMON) {
@@ -1241,9 +1229,9 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)
 			continue;
 		}
 
-		old_remaining_capacity = battery->state.remaining_capacity;
+		old_remaining_capacity = battery->capacity_now;
 
-		old_battery_present = battery->battery_present;
+		old_present = battery->present;
 
 		result = acpi_battery_select(battery);
 		if (result) {
@@ -1257,11 +1245,11 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)
 					"acpi_battery_get_present() failed"));
 		}
 
-		new_battery_present = battery->battery_present;
+		new_present = battery->present;
 
-		do_battery_init = ((old_battery_present != new_battery_present)
-				   && new_battery_present);
-		if (!new_battery_present)
+		do_battery_init = ((old_present != new_present)
+				   && new_present);
+		if (!new_present)
 			goto event;
 		if (do_ac_init || do_battery_init) {
 			result = acpi_battery_init(battery);
@@ -1277,7 +1265,7 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)
 
 		if ((data_type == DATA_TYPE_COMMON
 		     || data_type == DATA_TYPE_INFO)
-		    && new_battery_present) {
+		    && new_present) {
 			result = acpi_battery_get_info(battery);
 			if (result) {
 				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -1293,7 +1281,7 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)
 
 		if ((data_type == DATA_TYPE_COMMON
 		     || data_type == DATA_TYPE_STATE)
-		    && new_battery_present) {
+		    && new_present) {
 			result = acpi_battery_get_state(battery);
 			if (result) {
 				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -1309,7 +1297,7 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)
 
 		if ((data_type == DATA_TYPE_COMMON
 		     || data_type == DATA_TYPE_ALARM)
-		    && new_battery_present) {
+		    && new_present) {
 			result = acpi_battery_get_alarm(battery);
 			if (result) {
 				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -1326,14 +1314,14 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)
 
 	      event:
 
-		if (old_battery_present != new_battery_present || do_ac_init ||
+		if (old_present != new_present || do_ac_init ||
 		    old_remaining_capacity !=
-		    battery->state.remaining_capacity) {
+		    battery->capacity_now) {
 			sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
 			result = acpi_bus_generate_event4(ACPI_BATTERY_CLASS,
 							 dir_name,
 							 ACPI_SBS_BATTERY_NOTIFY_STATUS,
-							 new_battery_present);
+							 new_present);
 			if (result) {
 				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 						"acpi_bus_generate_event4() "
@@ -1420,7 +1408,7 @@ static int acpi_sbs_add(struct acpi_device *device)
 
 	acpi_sbsm_get_info(sbs);
 
-	if (!sbs->sbsm_present) {
+	if (!sbs->manager_present) {
 		result = acpi_battery_add(sbs, 0);
 		if (result) {
 			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -1429,7 +1417,7 @@ static int acpi_sbs_add(struct acpi_device *device)
 		}
 	} else {
 		for (id = 0; id < MAX_SBS_BAT; id++) {
-			if ((sbs->sbsm_batteries_supported & (1 << id))) {
+			if ((sbs->batteries_supported & (1 << id))) {
 				result = acpi_battery_add(sbs, id);
 				if (result) {
 					ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -1529,11 +1517,11 @@ static int __init acpi_sbs_init(void)
 	if (acpi_disabled)
 		return -ENODEV;
 
-	if (capacity_mode != DEF_CAPACITY_UNIT
-	    && capacity_mode != MAH_CAPACITY_UNIT
-	    && capacity_mode != MWH_CAPACITY_UNIT) {
+	if (mode != DEF_CAPACITY_UNIT
+	    && mode != MAH_CAPACITY_UNIT
+	    && mode != MWH_CAPACITY_UNIT) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"invalid capacity_mode = %d", capacity_mode));
+				"invalid mode = %d", mode));
 		return -EINVAL;
 	}
 


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

* [PATCH 10/12] ACPI: SBS: Make SBS reads table-driven.
  2007-08-16 14:25 [PATCH 01/12] ACPI: AC: Add sysfs interface Alexey Starikovskiy
                   ` (7 preceding siblings ...)
  2007-08-16 14:26 ` [PATCH 09/12] ACPI: SBS: Simplify data structures in SBS Alexey Starikovskiy
@ 2007-08-16 14:26 ` Alexey Starikovskiy
  2007-08-16 14:27 ` [PATCH 11/12] ACPI: SBS: Add support for power_supply class (and sysfs) Alexey Starikovskiy
  2007-08-16 14:27 ` [PATCH 12/12] ACPI: SBS: Add ACPI_PROCFS around procfs handling code Alexey Starikovskiy
  10 siblings, 0 replies; 14+ messages in thread
From: Alexey Starikovskiy @ 2007-08-16 14:26 UTC (permalink / raw)
  To: lenb, linux-acpi; +Cc: astarikovskiy

From: Alexey Starikovskiy <astarikovskiy@suse.de>

Re-factor SBS functions to use tables and cycles for repeated operations.
Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
---

 drivers/acpi/sbs.c | 1286 +++++++++++-----------------------------------------
 1 files changed, 275 insertions(+), 1011 deletions(-)

diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 4aee7fb..8651e5f 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -1,6 +1,8 @@
 /*
- *  acpi_sbs.c - ACPI Smart Battery System Driver ($Revision: 1.16 $)
+ *  sbs.c - ACPI Smart Battery System Driver ($Revision: 2.0 $)
  *
+ *  Copyright (c) 2007 Alexey Starikovskiy <astarikovskiy@suse.de>
+ *  Copyright (c) 2005-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com>
  *  Copyright (c) 2005 Rich Townsend <rhdt@bartol.udel.edu>
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -46,53 +48,34 @@
 #define ACPI_SBS_FILE_ALARM		"alarm"
 #define ACPI_BATTERY_DIR_NAME		"BAT%i"
 #define ACPI_AC_DIR_NAME		"AC0"
-#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 _COMPONENT			ACPI_SBS_COMPONENT
+enum acpi_sbs_device_addr {
+	ACPI_SBS_CHARGER = 0x9,
+	ACPI_SBS_MANAGER = 0xa,
+	ACPI_SBS_BATTERY = 0xb,
+};
+
+#define ACPI_SBS_NOTIFY_STATUS		0x80
+#define ACPI_SBS_NOTIFY_INFO		0x81
 
 ACPI_MODULE_NAME("sbs");
 
-MODULE_AUTHOR("Rich Townsend");
+MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>");
 MODULE_DESCRIPTION("Smart Battery System ACPI interface driver");
 MODULE_LICENSE("GPL");
 
-#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
+static unsigned int cache_time = 1000;
+module_param(cache_time, uint, 0644);
+MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
 
 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_SBS_BAT			4
 #define ACPI_SBS_BLOCK_MAX		32
 
-#define	UPDATE_DELAY	10
-
-/* 0 - every time, > 0 - by update_time */
-static unsigned int update_time = 120;
-
-static unsigned int mode = CAPACITY_UNIT;
-
-module_param(update_time, uint, 0644);
-module_param(mode, uint, 0444);
-
 static int acpi_sbs_add(struct acpi_device *device);
 static int acpi_sbs_remove(struct acpi_device *device, int type);
 static int acpi_sbs_resume(struct acpi_device *device);
@@ -117,486 +100,187 @@ static struct acpi_driver acpi_sbs_driver = {
 struct acpi_battery {
 	struct acpi_sbs *sbs;
 	struct proc_dir_entry *proc_entry;
-	int vscale;
-	int ipscale;
+	unsigned long update_time;
+	char name[8];
 	char manufacturer_name[ACPI_SBS_BLOCK_MAX];
 	char device_name[ACPI_SBS_BLOCK_MAX];
 	char device_chemistry[ACPI_SBS_BLOCK_MAX];
+	u32 alarm_capacity;
 	u16 full_charge_capacity;
 	u16 design_capacity;
 	u16 design_voltage;
 	u16 serial_number;
+	u16 cycle_count;
+	u16 temp_now;
 	u16 voltage_now;
 	s16 current_now;
+	s16 current_avg;
 	u16 capacity_now;
+	u16 state_of_charge;
 	u16 state;
-	u16 alarm_capacity;
 	u16 mode;
+	u16 spec;
 	u8 id;
-	u8 alive:1;
-	u8 init_state:1;
 	u8 present:1;
 };
 
 struct acpi_sbs {
 	struct acpi_device *device;
 	struct acpi_smb_hc *hc;
-	struct mutex mutex;
-	struct proc_dir_entry *ac_entry;
+	struct mutex lock;
+	struct proc_dir_entry *charger_entry;
 	struct acpi_battery battery[MAX_SBS_BAT];
-	int zombie;
-	struct timer_list update_timer;
-	int run_cnt;
-	int update_proc_flg;
-	u8 batteries_supported;
+	u8 batteries_supported:4;
 	u8 manager_present:1;
 	u8 charger_present:1;
 };
 
-static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type);
-static void acpi_sbs_update_time(void *data);
-
-static int sbs_zombie(struct acpi_sbs *sbs)
+static inline int battery_scale(int log)
 {
-	return (sbs->zombie);
+	int scale = 1;
+	while (log--)
+		scale *= 10;
+	return scale;
 }
 
-static int sbs_mutex_lock(struct acpi_sbs *sbs)
+static inline int acpi_battery_vscale(struct acpi_battery *battery)
 {
-	if (sbs_zombie(sbs)) {
-		return -ENODEV;
-	}
-	mutex_lock(&sbs->mutex);
-	return 0;
+	return battery_scale((battery->spec & 0x0f00) >> 8);
 }
 
-static void sbs_mutex_unlock(struct acpi_sbs *sbs)
+static inline int acpi_battery_ipscale(struct acpi_battery *battery)
 {
-	mutex_unlock(&sbs->mutex);
+	return battery_scale((battery->spec & 0xf000) >> 12);
 }
 
-/* --------------------------------------------------------------------------
-                            Smart Battery System Management
-   -------------------------------------------------------------------------- */
-
-static int acpi_check_update_proc(struct acpi_sbs *sbs)
+static inline int acpi_battery_mode(struct acpi_battery *battery)
 {
-	acpi_status status = AE_OK;
-
-	if (update_time == 0) {
-		sbs->update_proc_flg = 0;
-		return 0;
-	}
-	if (sbs->update_proc_flg == 0) {
-		status = acpi_os_execute(OSL_GPE_HANDLER,
-					 acpi_sbs_update_time, sbs);
-		if (status != AE_OK) {
-			ACPI_EXCEPTION((AE_INFO, status,
-					"acpi_os_execute() failed"));
-			return 1;
-		}
-		sbs->update_proc_flg = 1;
-	}
-	return 0;
+	return (battery->mode & 0x8000);
 }
 
-static int acpi_battery_get_present(struct acpi_battery *battery)
+static inline int acpi_battery_scale(struct acpi_battery *battery)
 {
-	s16 state;
-	int result = 0;
-	int is_present = 0;
-
-	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
-				    ACPI_SBSM_SMBUS_ADDR, 0x01, (u8 *)&state);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_smbus_read() failed"));
-	}
-	if (!result) {
-		is_present = (state & 0x000f) & (1 << battery->id);
-	}
-	battery->present = is_present;
-
-	return result;
+	return (acpi_battery_mode(battery) ? 10 : 1) *
+	    acpi_battery_ipscale(battery);
 }
 
-static int acpi_battery_select(struct acpi_battery *battery)
-{
-	struct acpi_sbs *sbs = battery->sbs;
-	int result = 0;
-	s16 state;
-	int foo;
-
-	if (sbs->manager_present) {
-
-		/* Take special care not to knobble other nibbles of
-		 * state (aka selector_state), since
-		 * it causes charging to halt on SBSELs */
+/* --------------------------------------------------------------------------
+                            Smart Battery System Management
+   -------------------------------------------------------------------------- */
 
-		result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
-					 ACPI_SBSM_SMBUS_ADDR, 0x01, (u8 *)&state);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_smbus_read() failed"));
-			goto end;
-		}
+struct acpi_battery_reader {
+	u8 command;		/* command for battery */
+	u8 mode;		/* word or block? */
+	size_t offset;		/* offset inside struct acpi_sbs_battery */
+};
 
-		foo = (state & 0x0fff) | (1 << (battery->id + 12));
-		result = acpi_smbus_write(battery->sbs->hc, SMBUS_WRITE_WORD,
-					  ACPI_SBSM_SMBUS_ADDR, 0x01, (u8 *)&foo, 2);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_smbus_write() failed"));
-			goto end;
-		}
-	}
+static struct acpi_battery_reader info_readers[] = {
+	{0x01, SMBUS_READ_WORD, offsetof(struct acpi_battery, alarm_capacity)},
+	{0x03, SMBUS_READ_WORD, offsetof(struct acpi_battery, mode)},
+	{0x10, SMBUS_READ_WORD, offsetof(struct acpi_battery, full_charge_capacity)},
+	{0x17, SMBUS_READ_WORD, offsetof(struct acpi_battery, cycle_count)},
+	{0x18, SMBUS_READ_WORD, offsetof(struct acpi_battery, design_capacity)},
+	{0x19, SMBUS_READ_WORD, offsetof(struct acpi_battery, design_voltage)},
+	{0x1a, SMBUS_READ_WORD, offsetof(struct acpi_battery, spec)},
+	{0x1c, SMBUS_READ_WORD, offsetof(struct acpi_battery, serial_number)},
+	{0x20, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, manufacturer_name)},
+	{0x21, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, device_name)},
+	{0x22, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, device_chemistry)},
+};
 
-      end:
-	return result;
-}
+static struct acpi_battery_reader state_readers[] = {
+	{0x08, SMBUS_READ_WORD, offsetof(struct acpi_battery, temp_now)},
+	{0x09, SMBUS_READ_WORD, offsetof(struct acpi_battery, voltage_now)},
+	{0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_now)},
+	{0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_avg)},
+	{0x0f, SMBUS_READ_WORD, offsetof(struct acpi_battery, capacity_now)},
+	{0x0e, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)},
+	{0x16, SMBUS_READ_WORD, offsetof(struct acpi_battery, state)},
+};
 
-static int acpi_sbsm_get_info(struct acpi_sbs *sbs)
+static int acpi_manager_get_info(struct acpi_sbs *sbs)
 {
 	int result = 0;
-	s16 battery_system_info;
-
-	result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBSM_SMBUS_ADDR, 0x04,
-				    (u8 *)&battery_system_info);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_smbus_read() failed"));
-		goto end;
-	}
-	sbs->manager_present = 1;
-
-      end:
+	u16 battery_system_info;
 
+	result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_MANAGER,
+				 0x04, (u8 *) & battery_system_info);
+	if (!result)
+		sbs->batteries_supported = battery_system_info & 0x000f;
 	return result;
 }
 
 static int acpi_battery_get_info(struct acpi_battery *battery)
 {
-	int result = 0;
-	s16 battery_mode;
-	s16 specification_info;
-
-	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x03,
-				    (u8 *)&battery_mode);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_smbus_read() failed"));
-		goto end;
-	}
-	battery->mode = (battery_mode & 0x8000) >> 15;
-
-	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x10,
-				    (u8 *)&battery->full_charge_capacity);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_smbus_read() failed"));
-		goto end;
-	}
-
-	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x18,
-				    (u8 *)&battery->design_capacity);
+	int i, result = 0;
 
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_smbus_read() failed"));
-		goto end;
-	}
-
-	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x19,
-				    (u8 *)&battery->design_voltage);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_smbus_read() failed"));
-		goto end;
+	for (i = 0; i < ARRAY_SIZE(info_readers); ++i) {
+		result = acpi_smbus_read(battery->sbs->hc, info_readers[i].mode,
+				    ACPI_SBS_BATTERY, info_readers[i].command,
+				    (u8 *) battery + info_readers[i].offset);
+		if (result)
+			break;
 	}
-
-	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x1a,
-				    (u8 *)&specification_info);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_smbus_read() failed"));
-		goto end;
-	}
-
-	switch ((specification_info & 0x0f00) >> 8) {
-	case 1:
-		battery->vscale = 10;
-		break;
-	case 2:
-		battery->vscale = 100;
-		break;
-	case 3:
-		battery->vscale = 1000;
-		break;
-	default:
-		battery->vscale = 1;
-	}
-
-	switch ((specification_info & 0xf000) >> 12) {
-	case 1:
-		battery->ipscale = 10;
-		break;
-	case 2:
-		battery->ipscale = 100;
-		break;
-	case 3:
-		battery->ipscale = 1000;
-		break;
-	default:
-		battery->ipscale = 1;
-	}
-
-	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x1c,
-				    (u8 *)&battery->serial_number);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_smbus_read() failed"));
-		goto end;
-	}
-
-	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_BLOCK, ACPI_SB_SMBUS_ADDR, 0x20,
-				   (u8 *)battery->manufacturer_name);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_str() failed"));
-		goto end;
-	}
-
-	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_BLOCK, ACPI_SB_SMBUS_ADDR, 0x21,
-				   (u8 *)battery->device_name);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_str() failed"));
-		goto end;
-	}
-
-	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_BLOCK, ACPI_SB_SMBUS_ADDR, 0x22,
-				   (u8 *)battery->device_chemistry);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_str() failed"));
-		goto end;
-	}
-
-      end:
 	return result;
 }
 
 static int acpi_battery_get_state(struct acpi_battery *battery)
 {
-	int result = 0;
-
-	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x09,
-				    (u8 *)&battery->voltage_now);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_smbus_read() failed"));
-		goto end;
-	}
-
-	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x0a,
-				    (u8 *)&battery->current_now);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_smbus_read() failed"));
-		goto end;
-	}
-
-	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x0f,
-				    (u8 *)&battery->capacity_now);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_smbus_read() failed"));
-		goto end;
-	}
-
-	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x16,
-				    (u8 *)&battery->state);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_smbus_read() failed"));
-		goto end;
-	}
-
-      end:
-	return result;
-}
-
-static int acpi_battery_get_alarm(struct acpi_battery *battery)
-{
-	int result = 0;
-
-	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x01,
-				    (u8 *)&battery->alarm_capacity);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_smbus_read() failed"));
-		goto end;
-	}
-
-      end:
-
-	return result;
-}
-
-static int acpi_battery_set_alarm(struct acpi_battery *battery,
-				  unsigned long alarm)
-{
-	int result = 0;
-	s16 battery_mode;
-	int foo;
+	int i, result = 0;
 
-	result = acpi_battery_select(battery);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_battery_select() failed"));
-		goto end;
-	}
-
-	/* If necessary, enable the alarm */
-
-	if (alarm > 0) {
-		result =
-		    acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x03,
-				       (u8 *)&battery_mode);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_smbus_read() failed"));
-			goto end;
-		}
-
-		battery_mode &= 0xbfff;
-		result =
-		    acpi_smbus_write(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x01,
-					(u8 *)&battery_mode, 2);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_smbus_write() failed"));
+	if (time_before(jiffies, battery->update_time +
+				msecs_to_jiffies(cache_time)))
+		return 0;
+	for (i = 0; i < ARRAY_SIZE(state_readers); ++i) {
+		result = acpi_smbus_read(battery->sbs->hc,
+					 state_readers[i].mode,
+					 ACPI_SBS_BATTERY,
+					 state_readers[i].command,
+				         (u8 *)battery +
+						state_readers[i].offset);
+		if (result)
 			goto end;
-		}
 	}
-
-	foo = alarm / (battery->mode ? 10 : 1);
-	result = acpi_smbus_write(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x01,
-				  (u8 *)&foo, 2);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_smbus_write() failed"));
-		goto end;
-	}
-
       end:
-
+	battery->update_time = jiffies;
 	return result;
 }
 
-static int acpi_battery_set_mode(struct acpi_battery *battery)
+static int acpi_battery_get_alarm(struct acpi_battery *battery)
 {
-	int result = 0;
-	s16 battery_mode;
-
-	if (mode == DEF_CAPACITY_UNIT) {
-		goto end;
-	}
-
-	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
-				 ACPI_SB_SMBUS_ADDR, 0x03, (u8 *)&battery_mode);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_smbus_read() failed"));
-		goto end;
-	}
-
-	if (mode == MAH_CAPACITY_UNIT) {
-		battery_mode &= 0x7fff;
-	} else {
-		battery_mode |= 0x8000;
-	}
-	result = acpi_smbus_write(battery->sbs->hc, SMBUS_READ_WORD,
-				  ACPI_SB_SMBUS_ADDR, 0x03, (u8 *)&battery_mode, 2);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_smbus_write() failed"));
-		goto end;
-	}
-
-	result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
-				 ACPI_SB_SMBUS_ADDR, 0x03, (u8 *)&battery_mode);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_smbus_read() failed"));
-		goto end;
-	}
-
-      end:
-	return result;
+	return acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
+				 ACPI_SBS_BATTERY, 0x01,
+				 (u8 *) & battery->alarm_capacity);
 }
 
-static int acpi_battery_init(struct acpi_battery *battery)
+static int acpi_battery_set_alarm(struct acpi_battery *battery)
 {
-	int result = 0;
-
-	result = acpi_battery_select(battery);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_battery_select() failed"));
-		goto end;
-	}
-
-	result = acpi_battery_set_mode(battery);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_battery_set_mode() failed"));
-		goto end;
-	}
-
-	result = acpi_battery_get_info(battery);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_battery_get_info() failed"));
-		goto end;
-	}
-
-	result = acpi_battery_get_state(battery);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_battery_get_state() failed"));
-		goto end;
-	}
+	struct acpi_sbs *sbs = battery->sbs;
+	u16 value;
+	return 0;
 
-	result = acpi_battery_get_alarm(battery);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_battery_get_alarm() failed"));
-		goto end;
+	if (sbs->manager_present) {
+		acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_MANAGER,
+				0x01, (u8 *)&value);
+		value &= 0x0fff;
+		value |= 1 << (battery->id + 12);
+		acpi_smbus_write(sbs->hc, SMBUS_WRITE_WORD, ACPI_SBS_MANAGER,
+				0x01, (u8 *)&value, 2);
 	}
-
-      end:
-	return result;
+	value = battery->alarm_capacity / (acpi_battery_mode(battery) ? 10 : 1);
+	return acpi_smbus_write(sbs->hc, SMBUS_WRITE_WORD, ACPI_SBS_BATTERY,
+				0x01, (u8 *)&value, 2);
 }
 
 static int acpi_ac_get_present(struct acpi_sbs *sbs)
 {
-	int result = 0;
-	s16 charger_status;
-
-	result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBC_SMBUS_ADDR, 0x13,
-				 (u8 *)&charger_status);
-
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_smbus_read() failed"));
-		goto end;
-	}
-
-	sbs->charger_present = (charger_status & 0x8000) >> 15;
-
-      end:
+	int result;
+	u16 status;
 
+	result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_CHARGER,
+				 0x13, (u8 *) & status);
+	if (!result)
+		sbs->charger_present = (status >> 15) & 0x1;
 	return result;
 }
 
@@ -607,7 +291,7 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)
 /* Generic Routines */
 
 static int
-acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
+acpi_sbs_add_fs(struct proc_dir_entry **dir,
 			struct proc_dir_entry *parent_dir,
 			char *dir_name,
 			struct file_operations *info_fops,
@@ -669,7 +353,7 @@ acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
 }
 
 static void
-acpi_sbs_generic_remove_fs(struct proc_dir_entry **dir,
+acpi_sbs_remove_fs(struct proc_dir_entry **dir,
 			   struct proc_dir_entry *parent_dir)
 {
 
@@ -687,75 +371,47 @@ acpi_sbs_generic_remove_fs(struct proc_dir_entry **dir,
 
 static struct proc_dir_entry *acpi_battery_dir = NULL;
 
+static inline char *acpi_battery_units(struct acpi_battery *battery)
+{
+	return acpi_battery_mode(battery) ? " mWh" : " mAh";
+}
+
+
 static int acpi_battery_read_info(struct seq_file *seq, void *offset)
 {
 	struct acpi_battery *battery = seq->private;
 	struct acpi_sbs *sbs = battery->sbs;
-	int cscale;
 	int result = 0;
 
-	if (sbs_mutex_lock(sbs)) {
-		return -ENODEV;
-	}
+	mutex_lock(&sbs->lock);
 
-	result = acpi_check_update_proc(sbs);
-	if (result)
+	seq_printf(seq, "present:                 %s\n",
+		   (battery->present) ? "yes" : "no");
+	if (!battery->present)
 		goto end;
 
-	if (update_time == 0) {
-		result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_INFO);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_sbs_update_run() failed"));
-		}
-	}
-
-	if (battery->present) {
-		seq_printf(seq, "present:                 yes\n");
-	} else {
-		seq_printf(seq, "present:                 no\n");
-		goto end;
-	}
-
-	if (battery->mode) {
-		cscale = battery->vscale * battery->ipscale;
-	} else {
-		cscale = battery->ipscale;
-	}
 	seq_printf(seq, "design capacity:         %i%s\n",
-		   battery->design_capacity * cscale,
-		   battery->mode ? "0 mWh" : " mAh");
-
+		   battery->design_capacity * acpi_battery_scale(battery),
+		   acpi_battery_units(battery));
 	seq_printf(seq, "last full capacity:      %i%s\n",
-		   battery->full_charge_capacity * cscale,
-		   battery->mode ? "0 mWh" : " mAh");
-
+		   battery->full_charge_capacity * acpi_battery_scale(battery),
+		   acpi_battery_units(battery));
 	seq_printf(seq, "battery technology:      rechargeable\n");
-
 	seq_printf(seq, "design voltage:          %i mV\n",
-		   battery->design_voltage * battery->vscale);
-
+		   battery->design_voltage * acpi_battery_vscale(battery));
 	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->device_name);
-
+	seq_printf(seq, "model number:            %s\n", battery->device_name);
 	seq_printf(seq, "serial number:           %i\n",
 		   battery->serial_number);
-
 	seq_printf(seq, "battery type:            %s\n",
 		   battery->device_chemistry);
-
 	seq_printf(seq, "OEM info:                %s\n",
 		   battery->manufacturer_name);
-
       end:
-
-	sbs_mutex_unlock(sbs);
-
+	mutex_unlock(&sbs->lock);
 	return result;
 }
 
@@ -769,73 +425,29 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
 	struct acpi_battery *battery = seq->private;
 	struct acpi_sbs *sbs = battery->sbs;
 	int result = 0;
-	int cscale;
-	int foo;
-
-	if (sbs_mutex_lock(sbs)) {
-		return -ENODEV;
-	}
-
-	result = acpi_check_update_proc(sbs);
-	if (result)
-		goto end;
-
-	if (update_time == 0) {
-		result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_STATE);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_sbs_update_run() failed"));
-		}
-	}
 
-	if (battery->present) {
-		seq_printf(seq, "present:                 yes\n");
-	} else {
-		seq_printf(seq, "present:                 no\n");
+	mutex_lock(&sbs->lock);
+	seq_printf(seq, "present:                 %s\n",
+		   (battery->present) ? "yes" : "no");
+	if (!battery->present)
 		goto end;
-	}
-
-	if (battery->mode) {
-		cscale = battery->vscale * battery->ipscale;
-	} else {
-		cscale = battery->ipscale;
-	}
-
-	if (battery->state & 0x0010) {
-		seq_printf(seq, "capacity state:          critical\n");
-	} else {
-		seq_printf(seq, "capacity state:          ok\n");
-	}
-
-	foo = (s16) battery->current_now * battery->ipscale;
-	if (battery->mode) {
-		foo = foo * battery->design_voltage / 1000;
-	}
-	if (battery->current_now < 0) {
-		seq_printf(seq, "charging state:          discharging\n");
-		seq_printf(seq, "present rate:            %d %s\n",
-			   -foo, battery->mode ? "mW" : "mA");
-	} else if (battery->current_now > 0) {
-		seq_printf(seq, "charging state:          charging\n");
-		seq_printf(seq, "present rate:            %d %s\n",
-			   foo, battery->mode ? "mW" : "mA");
-	} else {
-		seq_printf(seq, "charging state:          charged\n");
-		seq_printf(seq, "present rate:            0 %s\n",
-			   battery->mode ? "mW" : "mA");
-	}
 
+	acpi_battery_get_state(battery);
+	seq_printf(seq, "capacity state:          %s\n",
+		   (battery->state & 0x0010) ? "critical" : "ok");
+	seq_printf(seq, "charging state:          %s\n",
+		   (battery->current_now < 0) ? "discharging" :
+		   ((battery->current_now > 0) ? "charging" : "charged"));
+	seq_printf(seq, "present rate:            %d mA\n",
+		   abs(battery->current_now) * acpi_battery_ipscale(battery));
 	seq_printf(seq, "remaining capacity:      %i%s\n",
-		   battery->capacity_now * cscale,
-		   battery->mode ? "0 mWh" : " mAh");
-
+		   battery->capacity_now * acpi_battery_scale(battery),
+		   acpi_battery_units(battery));
 	seq_printf(seq, "present voltage:         %i mV\n",
-		   battery->voltage_now * battery->vscale);
+		   battery->voltage_now * acpi_battery_vscale(battery));
 
       end:
-
-	sbs_mutex_unlock(sbs);
-
+	mutex_unlock(&sbs->lock);
 	return result;
 }
 
@@ -849,48 +461,25 @@ static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
 	struct acpi_battery *battery = seq->private;
 	struct acpi_sbs *sbs = battery->sbs;
 	int result = 0;
-	int cscale;
-
-	if (sbs_mutex_lock(sbs)) {
-		return -ENODEV;
-	}
 
-	result = acpi_check_update_proc(sbs);
-	if (result)
-		goto end;
-
-	if (update_time == 0) {
-		result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_ALARM);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_sbs_update_run() failed"));
-		}
-	}
+	mutex_lock(&sbs->lock);
 
 	if (!battery->present) {
 		seq_printf(seq, "present:                 no\n");
 		goto end;
 	}
 
-	if (battery->mode) {
-		cscale = battery->vscale * battery->ipscale;
-	} else {
-		cscale = battery->ipscale;
-	}
-
+	acpi_battery_get_alarm(battery);
 	seq_printf(seq, "alarm:                   ");
-	if (battery->alarm_capacity) {
+	if (battery->alarm_capacity)
 		seq_printf(seq, "%i%s\n",
-			   battery->alarm_capacity * cscale,
-			   battery->mode ? "0 mWh" : " mAh");
-	} else {
+			   battery->alarm_capacity *
+			   acpi_battery_scale(battery),
+			   acpi_battery_units(battery));
+	else
 		seq_printf(seq, "disabled\n");
-	}
-
       end:
-
-	sbs_mutex_unlock(sbs);
-
+	mutex_unlock(&sbs->lock);
 	return result;
 }
 
@@ -902,59 +491,28 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer,
 	struct acpi_battery *battery = seq->private;
 	struct acpi_sbs *sbs = battery->sbs;
 	char alarm_string[12] = { '\0' };
-	int result, old_alarm, new_alarm;
-
-	if (sbs_mutex_lock(sbs)) {
-		return -ENODEV;
-	}
-
-	result = acpi_check_update_proc(sbs);
-	if (result)
-		goto end;
-
+	int result = 0;
+	mutex_lock(&sbs->lock);
 	if (!battery->present) {
 		result = -ENODEV;
 		goto end;
 	}
-
 	if (count > sizeof(alarm_string) - 1) {
 		result = -EINVAL;
 		goto end;
 	}
-
 	if (copy_from_user(alarm_string, buffer, count)) {
 		result = -EFAULT;
 		goto end;
 	}
-
 	alarm_string[count] = 0;
-
-	old_alarm = battery->alarm_capacity;
-	new_alarm = simple_strtoul(alarm_string, NULL, 0);
-
-	result = acpi_battery_set_alarm(battery, new_alarm);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_battery_set_alarm() failed"));
-		acpi_battery_set_alarm(battery, old_alarm);
-		goto end;
-	}
-	result = acpi_battery_get_alarm(battery);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_battery_get_alarm() failed"));
-		acpi_battery_set_alarm(battery, old_alarm);
-		goto end;
-	}
-
+	battery->alarm_capacity = simple_strtoul(alarm_string, NULL, 0);
+	acpi_battery_set_alarm(battery);
       end:
-	sbs_mutex_unlock(sbs);
-
-	if (result) {
+	mutex_unlock(&sbs->lock);
+	if (result)
 		return result;
-	} else {
-		return count;
-	}
+	return count;
 }
 
 static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
@@ -993,26 +551,15 @@ static struct proc_dir_entry *acpi_ac_dir = NULL;
 
 static int acpi_ac_read_state(struct seq_file *seq, void *offset)
 {
-	struct acpi_sbs *sbs = seq->private;
-	int result;
 
-	if (sbs_mutex_lock(sbs)) {
-		return -ENODEV;
-	}
+	struct acpi_sbs *sbs = seq->private;
 
-	if (update_time == 0) {
-		result = acpi_sbs_update_run(sbs, -1, DATA_TYPE_AC_STATE);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_sbs_update_run() failed"));
-		}
-	}
+	mutex_lock(&sbs->lock);
 
 	seq_printf(seq, "state:                   %s\n",
 		   sbs->charger_present ? "on-line" : "off-line");
 
-	sbs_mutex_unlock(sbs);
-
+	mutex_unlock(&sbs->lock);
 	return 0;
 }
 
@@ -1035,67 +582,54 @@ static struct file_operations acpi_ac_state_fops = {
 
 /* Smart Battery */
 
-static int acpi_battery_add(struct acpi_sbs *sbs, int id)
+static int acpi_battery_read(struct acpi_battery *battery)
 {
-	int is_present;
-	int result;
-	char dir_name[32];
-	struct acpi_battery *battery;
+	int result = 0, saved_present = battery->present;
+	u16 state;
 
-	battery = &sbs->battery[id];
+	if (battery->sbs->manager_present) {
+		result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
+				ACPI_SBS_MANAGER, 0x01, (u8 *)&state);
+		if (!result)
+			battery->present = state & (1 << battery->id);
+		state &= 0x0fff;
+		state |= 1 << (battery->id + 12);
+		acpi_smbus_write(battery->sbs->hc, SMBUS_WRITE_WORD,
+				  ACPI_SBS_MANAGER, 0x01, (u8 *)&state, 2);
+	} else if (battery->id == 0)
+		battery->present = 1;
+	if (result || !battery->present)
+		return result;
 
-	battery->alive = 0;
+	if (saved_present != battery->present) {
+		battery->update_time = 0;
+		result = acpi_battery_get_info(battery);
+		if (result)
+			return result;
+	}
+	result = acpi_battery_get_state(battery);
+	return result;
+}
 
-	battery->init_state = 0;
+static int acpi_battery_add(struct acpi_sbs *sbs, int id)
+{
+	int result;
+	struct acpi_battery *battery = &sbs->battery[id];
 	battery->id = id;
 	battery->sbs = sbs;
+	battery->update_time = 0;
+	result = acpi_battery_read(battery);
+	if (result)
+		return result;
 
-	result = acpi_battery_select(battery);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_battery_select() failed"));
-		goto end;
-	}
-
-	result = acpi_battery_get_present(battery);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_battery_get_present() failed"));
-		goto end;
-	}
-
-	is_present = battery->present;
-
-	if (is_present) {
-		result = acpi_battery_init(battery);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_battery_init() failed"));
-			goto end;
-		}
-		battery->init_state = 1;
-	}
-
-	sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
-
-	result = acpi_sbs_generic_add_fs(&battery->proc_entry,
-					 acpi_battery_dir,
-					 dir_name,
-					 &acpi_battery_info_fops,
-					 &acpi_battery_state_fops,
-					 &acpi_battery_alarm_fops, battery);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_generic_add_fs() failed"));
-		goto end;
-	}
-	battery->alive = 1;
-
+	sprintf(battery->name, ACPI_BATTERY_DIR_NAME, id);
+	acpi_sbs_add_fs(&battery->proc_entry, acpi_battery_dir,
+			battery->name, &acpi_battery_info_fops,
+			&acpi_battery_state_fops, &acpi_battery_alarm_fops,
+			battery);
 	printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",
-	       ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), dir_name,
-	       sbs->battery->present ? "present" : "absent");
-
-      end:
+	       ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
+	       battery->name, sbs->battery->present ? "present" : "absent");
 	return result;
 }
 
@@ -1103,348 +637,105 @@ static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
 {
 
 	if (sbs->battery[id].proc_entry) {
-		acpi_sbs_generic_remove_fs(&(sbs->battery[id].proc_entry),
-					   acpi_battery_dir);
+		acpi_sbs_remove_fs(&(sbs->battery[id].proc_entry),
+				   acpi_battery_dir);
 	}
 }
 
-static int acpi_ac_add(struct acpi_sbs *sbs)
+static int acpi_charger_add(struct acpi_sbs *sbs)
 {
 	int result;
 
 	result = acpi_ac_get_present(sbs);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_ac_get_present() failed"));
+	if (result)
 		goto end;
-	}
-
-	result = acpi_sbs_generic_add_fs(&sbs->ac_entry,
-					 acpi_ac_dir,
-					 ACPI_AC_DIR_NAME,
-					 NULL, &acpi_ac_state_fops, NULL, sbs);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_generic_add_fs() failed"));
+	result = acpi_sbs_add_fs(&sbs->charger_entry, acpi_ac_dir,
+				 ACPI_AC_DIR_NAME, NULL,
+				 &acpi_ac_state_fops, NULL, sbs);
+	if (result)
 		goto end;
-	}
-
 	printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",
 	       ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
 	       ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line");
-
       end:
-
 	return result;
 }
 
-static void acpi_ac_remove(struct acpi_sbs *sbs)
+static void acpi_charger_remove(struct acpi_sbs *sbs)
 {
 
-	if (sbs->ac_entry) {
-		acpi_sbs_generic_remove_fs(&sbs->ac_entry, acpi_ac_dir);
-	}
-}
-
-static void acpi_sbs_update_time_run(unsigned long data)
-{
-	acpi_os_execute(OSL_GPE_HANDLER, acpi_sbs_update_time, (void *)data);
+	if (sbs->charger_entry)
+		acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir);
 }
 
-static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)
+void acpi_sbs_callback(void *context)
 {
-	struct acpi_battery *battery;
-	int result = 0, cnt;
-	int old_ac_present = -1;
-	int old_present = -1;
-	int new_ac_present = -1;
-	int new_present = -1;
-	int id_min = 0, id_max = MAX_SBS_BAT - 1;
-	char dir_name[32];
-	int do_battery_init = 0, do_ac_init = 0;
-	int old_remaining_capacity = 0;
-	int update_battery = 1;
-	int up_tm = update_time;
-
-	if (sbs_zombie(sbs)) {
-		goto end;
-	}
-
-	if (id >= 0) {
-		id_min = id_max = id;
-	}
-
-	if (data_type == DATA_TYPE_COMMON && up_tm > 0) {
-		cnt = up_tm / (up_tm > UPDATE_DELAY ? UPDATE_DELAY : up_tm);
-		if (sbs->run_cnt % cnt != 0) {
-			update_battery = 0;
-		}
-	}
-
-	sbs->run_cnt++;
-
-	if (!update_battery) {
-		goto end;
-	}
-
-	old_ac_present = sbs->charger_present;
-
-	result = acpi_ac_get_present(sbs);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_ac_get_present() failed"));
-	}
-
-	new_ac_present = sbs->charger_present;
-
-	do_ac_init = (old_ac_present != new_ac_present);
-	if (sbs->run_cnt == 1 && data_type == DATA_TYPE_COMMON) {
-		do_ac_init = 1;
-	}
-
-	if (do_ac_init) {
-		result = acpi_bus_generate_event4(ACPI_AC_CLASS,
-						 ACPI_AC_DIR_NAME,
-						 ACPI_SBS_AC_NOTIFY_STATUS,
-						 new_ac_present);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_bus_generate_event4() failed"));
-		}
-	}
-
-	if (data_type == DATA_TYPE_COMMON) {
-		if (!do_ac_init && !update_battery) {
-			goto end;
-		}
-	}
-
-	if (data_type == DATA_TYPE_AC_STATE && !do_ac_init) {
-		goto end;
+	int id;
+	struct acpi_sbs *sbs = context;
+	struct acpi_battery *bat;
+	u8 saved_charger_state = sbs->charger_present;
+	u8 saved_battery_state;
+	acpi_ac_get_present(sbs);
+	if (sbs->charger_present != saved_charger_state) {
+		acpi_bus_generate_event4(ACPI_AC_CLASS, ACPI_AC_DIR_NAME,
+					 ACPI_SBS_NOTIFY_STATUS,
+					 sbs->charger_present);
 	}
-
-	for (id = id_min; id <= id_max; id++) {
-		battery = &sbs->battery[id];
-		if (battery->alive == 0) {
-			continue;
-		}
-
-		old_remaining_capacity = battery->capacity_now;
-
-		old_present = battery->present;
-
-		result = acpi_battery_select(battery);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_battery_select() failed"));
-		}
-
-		result = acpi_battery_get_present(battery);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_battery_get_present() failed"));
-		}
-
-		new_present = battery->present;
-
-		do_battery_init = ((old_present != new_present)
-				   && new_present);
-		if (!new_present)
-			goto event;
-		if (do_ac_init || do_battery_init) {
-			result = acpi_battery_init(battery);
-			if (result) {
-				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-						"acpi_battery_init() "
-						"failed"));
-			}
-		}
-		if (sbs_zombie(sbs)) {
-			goto end;
-		}
-
-		if ((data_type == DATA_TYPE_COMMON
-		     || data_type == DATA_TYPE_INFO)
-		    && new_present) {
-			result = acpi_battery_get_info(battery);
-			if (result) {
-				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-						"acpi_battery_get_info() failed"));
-			}
-		}
-		if (data_type == DATA_TYPE_INFO) {
-			continue;
-		}
-		if (sbs_zombie(sbs)) {
-			goto end;
-		}
-
-		if ((data_type == DATA_TYPE_COMMON
-		     || data_type == DATA_TYPE_STATE)
-		    && new_present) {
-			result = acpi_battery_get_state(battery);
-			if (result) {
-				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-						"acpi_battery_get_state() failed"));
-			}
-		}
-		if (data_type == DATA_TYPE_STATE) {
-			goto event;
-		}
-		if (sbs_zombie(sbs)) {
-			goto end;
-		}
-
-		if ((data_type == DATA_TYPE_COMMON
-		     || data_type == DATA_TYPE_ALARM)
-		    && new_present) {
-			result = acpi_battery_get_alarm(battery);
-			if (result) {
-				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-						"acpi_battery_get_alarm() "
-						"failed"));
-			}
-		}
-		if (data_type == DATA_TYPE_ALARM) {
-			continue;
-		}
-		if (sbs_zombie(sbs)) {
-			goto end;
-		}
-
-	      event:
-
-		if (old_present != new_present || do_ac_init ||
-		    old_remaining_capacity !=
-		    battery->capacity_now) {
-			sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
-			result = acpi_bus_generate_event4(ACPI_BATTERY_CLASS,
-							 dir_name,
-							 ACPI_SBS_BATTERY_NOTIFY_STATUS,
-							 new_present);
-			if (result) {
-				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-						"acpi_bus_generate_event4() "
-						"failed"));
-			}
+	if (sbs->manager_present) {
+		for (id = 0; id < MAX_SBS_BAT; ++id) {
+			if (!(sbs->batteries_supported & (1 << id)))
+				continue;
+			bat = &sbs->battery[id];
+			saved_battery_state = bat->present;
+			acpi_battery_read(bat);
+			if (saved_battery_state == bat->present)
+				continue;
+			acpi_bus_generate_event4(ACPI_BATTERY_CLASS,
+						bat->name,
+						ACPI_SBS_NOTIFY_STATUS,
+						bat->present);
 		}
 	}
-
-      end:
-
-	return result;
 }
 
-static void acpi_sbs_update_time(void *data)
-{
-	struct acpi_sbs *sbs = data;
-	unsigned long delay = -1;
-	int result;
-	unsigned int up_tm = update_time;
-
-	if (sbs_mutex_lock(sbs))
-		return;
-
-	result = acpi_sbs_update_run(sbs, -1, DATA_TYPE_COMMON);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_update_run() failed"));
-	}
-
-	if (sbs_zombie(sbs)) {
-		goto end;
-	}
-
-	if (!up_tm) {
-		if (timer_pending(&sbs->update_timer))
-			del_timer(&sbs->update_timer);
-	} else {
-		delay = (up_tm > UPDATE_DELAY ? UPDATE_DELAY : up_tm);
-		delay = jiffies + HZ * delay;
-		if (timer_pending(&sbs->update_timer)) {
-			mod_timer(&sbs->update_timer, delay);
-		} else {
-			sbs->update_timer.data = (unsigned long)data;
-			sbs->update_timer.function = acpi_sbs_update_time_run;
-			sbs->update_timer.expires = delay;
-			add_timer(&sbs->update_timer);
-		}
-	}
-
-      end:
-
-	sbs_mutex_unlock(sbs);
-}
+static int acpi_sbs_remove(struct acpi_device *device, int type);
 
 static int acpi_sbs_add(struct acpi_device *device)
 {
-	struct acpi_sbs *sbs = NULL;
-	int result = 0, remove_result = 0;
+	struct acpi_sbs *sbs;
+	int result = 0;
 	int id;
 
 	sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL);
 	if (!sbs) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "kzalloc() failed"));
 		result = -ENOMEM;
 		goto end;
 	}
 
-	mutex_init(&sbs->mutex);
-
-	sbs_mutex_lock(sbs);
+	mutex_init(&sbs->lock);
 
-	sbs->device = device;
 	sbs->hc = acpi_driver_data(device->parent);
-
+	sbs->device = device;
 	strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_SBS_CLASS);
 	acpi_driver_data(device) = sbs;
 
-	result = acpi_ac_add(sbs);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed"));
-		goto end;
-	}
-
-	acpi_sbsm_get_info(sbs);
-
-	if (!sbs->manager_present) {
-		result = acpi_battery_add(sbs, 0);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_battery_add() failed"));
-			goto end;
-		}
-	} else {
-		for (id = 0; id < MAX_SBS_BAT; id++) {
-			if ((sbs->batteries_supported & (1 << id))) {
-				result = acpi_battery_add(sbs, id);
-				if (result) {
-					ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-							"acpi_battery_add() failed"));
-					goto end;
-				}
-			}
-		}
-	}
-
-	init_timer(&sbs->update_timer);
-	result = acpi_check_update_proc(sbs);
+	result = acpi_charger_add(sbs);
 	if (result)
 		goto end;
 
+	result = acpi_manager_get_info(sbs);
+	if (!result) {
+		sbs->manager_present = 1;
+		for (id = 0; id < MAX_SBS_BAT; ++id)
+			if ((sbs->batteries_supported & (1 << id)))
+				acpi_battery_add(sbs, id);
+	} else
+		acpi_battery_add(sbs, 0);
+	acpi_smbus_register_callback(sbs->hc, acpi_sbs_callback, sbs);
       end:
-
-	sbs_mutex_unlock(sbs);
-
-	if (result) {
-		remove_result = acpi_sbs_remove(device, 0);
-		if (remove_result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_sbs_remove() failed"));
-		}
-	}
-
+	if (result)
+		acpi_sbs_remove(device, 0);
 	return result;
 }
 
@@ -1453,34 +744,19 @@ static int acpi_sbs_remove(struct acpi_device *device, int type)
 	struct acpi_sbs *sbs;
 	int id;
 
-	if (!device) {
+	if (!device)
 		return -EINVAL;
-	}
-
 	sbs = acpi_driver_data(device);
-	if (!sbs) {
+	if (!sbs)
 		return -EINVAL;
-	}
-
-	sbs_mutex_lock(sbs);
-
-	sbs->zombie = 1;
-	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++) {
+	mutex_lock(&sbs->lock);
+	acpi_smbus_unregister_callback(sbs->hc);
+	for (id = 0; id < MAX_SBS_BAT; ++id)
 		acpi_battery_remove(sbs, id);
-	}
-
-	acpi_ac_remove(sbs);
-
-	sbs_mutex_unlock(sbs);
-
-	mutex_destroy(&sbs->mutex);
-
+	acpi_charger_remove(sbs);
+	mutex_unlock(&sbs->lock);
+	mutex_destroy(&sbs->lock);
 	kfree(sbs);
-
 	return 0;
 }
 
@@ -1499,14 +775,10 @@ static void acpi_sbs_rmdirs(void)
 static int acpi_sbs_resume(struct acpi_device *device)
 {
 	struct acpi_sbs *sbs;
-
 	if (!device)
 		return -EINVAL;
-
 	sbs = device->driver_data;
-
-	sbs->run_cnt = 0;
-
+	acpi_sbs_callback(sbs);
 	return 0;
 }
 
@@ -1517,14 +789,6 @@ static int __init acpi_sbs_init(void)
 	if (acpi_disabled)
 		return -ENODEV;
 
-	if (mode != DEF_CAPACITY_UNIT
-	    && mode != MAH_CAPACITY_UNIT
-	    && mode != MWH_CAPACITY_UNIT) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"invalid mode = %d", mode));
-		return -EINVAL;
-	}
-
 	acpi_ac_dir = acpi_lock_ac_dir();
 	if (!acpi_ac_dir) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,


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

* [PATCH 11/12] ACPI: SBS: Add support for power_supply class (and sysfs)
  2007-08-16 14:25 [PATCH 01/12] ACPI: AC: Add sysfs interface Alexey Starikovskiy
                   ` (8 preceding siblings ...)
  2007-08-16 14:26 ` [PATCH 10/12] ACPI: SBS: Make SBS reads table-driven Alexey Starikovskiy
@ 2007-08-16 14:27 ` Alexey Starikovskiy
  2007-08-16 14:27 ` [PATCH 12/12] ACPI: SBS: Add ACPI_PROCFS around procfs handling code Alexey Starikovskiy
  10 siblings, 0 replies; 14+ messages in thread
From: Alexey Starikovskiy @ 2007-08-16 14:27 UTC (permalink / raw)
  To: lenb, linux-acpi; +Cc: astarikovskiy

From: Alexey Starikovskiy <aystarik@gmail.com>

Add support for power_supply class and sysfs interface of it.
Refer to Documentation/power_supply_class.txt for interface description.

Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
---

 drivers/acpi/sbs.c |  331 +++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 250 insertions(+), 81 deletions(-)

diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 8651e5f..87bee1e 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -28,17 +28,23 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
+
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <asm/uaccess.h>
+
 #include <linux/acpi.h>
 #include <linux/timer.h>
 #include <linux/jiffies.h>
 #include <linux/delay.h>
 
+#if defined(CONFIG_POWER_SUPPLY) || defined (CONFIG_POWER_SUPPLY_MODULE)
+#define ENABLE_POWER_SUPPLY
+#include <linux/power_supply.h>
+#endif
+
 #include "sbshc.h"
 
-#define ACPI_SBS_COMPONENT		0x00080000
 #define ACPI_SBS_CLASS			"sbs"
 #define ACPI_AC_CLASS			"ac_adapter"
 #define ACPI_BATTERY_CLASS		"battery"
@@ -58,8 +64,6 @@ enum acpi_sbs_device_addr {
 #define ACPI_SBS_NOTIFY_STATUS		0x80
 #define ACPI_SBS_NOTIFY_INFO		0x81
 
-ACPI_MODULE_NAME("sbs");
-
 MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>");
 MODULE_DESCRIPTION("Smart Battery System ACPI interface driver");
 MODULE_LICENSE("GPL");
@@ -76,28 +80,16 @@ extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
 #define MAX_SBS_BAT			4
 #define ACPI_SBS_BLOCK_MAX		32
 
-static int acpi_sbs_add(struct acpi_device *device);
-static int acpi_sbs_remove(struct acpi_device *device, int type);
-static int acpi_sbs_resume(struct acpi_device *device);
-
 static const struct acpi_device_id sbs_device_ids[] = {
 	{"ACPI0002", 0},
 	{"", 0},
 };
 MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
 
-static struct acpi_driver acpi_sbs_driver = {
-	.name = "sbs",
-	.class = ACPI_SBS_CLASS,
-	.ids = sbs_device_ids,
-	.ops = {
-		.add = acpi_sbs_add,
-		.remove = acpi_sbs_remove,
-		.resume = acpi_sbs_resume,
-		},
-};
-
 struct acpi_battery {
+#ifdef ENABLE_POWER_SUPPLY
+	struct power_supply bat;
+#endif
 	struct acpi_sbs *sbs;
 	struct proc_dir_entry *proc_entry;
 	unsigned long update_time;
@@ -105,7 +97,7 @@ struct acpi_battery {
 	char manufacturer_name[ACPI_SBS_BLOCK_MAX];
 	char device_name[ACPI_SBS_BLOCK_MAX];
 	char device_chemistry[ACPI_SBS_BLOCK_MAX];
-	u32 alarm_capacity;
+	u16 alarm_capacity;
 	u16 full_charge_capacity;
 	u16 design_capacity;
 	u16 design_voltage;
@@ -124,7 +116,12 @@ struct acpi_battery {
 	u8 present:1;
 };
 
+#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
+
 struct acpi_sbs {
+#ifdef ENABLE_POWER_SUPPLY
+	struct power_supply charger;
+#endif
 	struct acpi_device *device;
 	struct acpi_smb_hc *hc;
 	struct mutex lock;
@@ -135,6 +132,8 @@ struct acpi_sbs {
 	u8 charger_present:1;
 };
 
+#define to_acpi_sbs(x) container_of(x, struct acpi_sbs, charger)
+
 static inline int battery_scale(int log)
 {
 	int scale = 1;
@@ -164,6 +163,146 @@ static inline int acpi_battery_scale(struct acpi_battery *battery)
 	    acpi_battery_ipscale(battery);
 }
 
+#ifdef ENABLE_POWER_SUPPLY
+static int sbs_get_ac_property(struct power_supply *psy,
+			       enum power_supply_property psp,
+			       union power_supply_propval *val)
+{
+	struct acpi_sbs *sbs = to_acpi_sbs(psy);
+	switch (psp) {
+	case POWER_SUPPLY_PROP_ONLINE:
+		val->intval = sbs->charger_present;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int acpi_battery_technology(struct acpi_battery *battery)
+{
+	if (!strcasecmp("NiCd", battery->device_chemistry))
+		return POWER_SUPPLY_TECHNOLOGY_NiCd;
+	if (!strcasecmp("NiMH", battery->device_chemistry))
+		return POWER_SUPPLY_TECHNOLOGY_NiMH;
+	if (!strcasecmp("LION", battery->device_chemistry))
+		return POWER_SUPPLY_TECHNOLOGY_LION;
+	if (!strcasecmp("LiP", battery->device_chemistry))
+		return POWER_SUPPLY_TECHNOLOGY_LIPO;
+	return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
+}
+
+static int acpi_sbs_battery_get_property(struct power_supply *psy,
+					 enum power_supply_property psp,
+					 union power_supply_propval *val)
+{
+	struct acpi_battery *battery = to_acpi_battery(psy);
+
+	if ((!battery->present) && psp != POWER_SUPPLY_PROP_PRESENT)
+		return -ENODEV;
+	switch (psp) {
+	case POWER_SUPPLY_PROP_STATUS:
+		if (battery->current_now < 0)
+			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+		else if (battery->current_now > 0)
+			val->intval = POWER_SUPPLY_STATUS_CHARGING;
+		else
+			val->intval = POWER_SUPPLY_STATUS_FULL;
+		break;
+	case POWER_SUPPLY_PROP_PRESENT:
+		val->intval = battery->present;
+		break;
+	case POWER_SUPPLY_PROP_TECHNOLOGY:
+		val->intval = acpi_battery_technology(battery);
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+		val->intval = battery->design_voltage *
+			acpi_battery_vscale(battery) * 1000;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		val->intval = battery->voltage_now *
+				acpi_battery_vscale(battery) * 1000;
+		break;
+	case POWER_SUPPLY_PROP_CURRENT_NOW:
+		val->intval = abs(battery->current_now) *
+				acpi_battery_ipscale(battery) * 1000;
+		break;
+	case POWER_SUPPLY_PROP_CURRENT_AVG:
+		val->intval = abs(battery->current_avg) *
+				acpi_battery_ipscale(battery) * 1000;
+		break;
+	case POWER_SUPPLY_PROP_CAPACITY:
+		val->intval = battery->state_of_charge;
+		break;
+	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
+	case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
+		val->intval = battery->design_capacity *
+			acpi_battery_scale(battery) * 1000;
+		break;
+	case POWER_SUPPLY_PROP_CHARGE_FULL:
+	case POWER_SUPPLY_PROP_ENERGY_FULL:
+		val->intval = battery->full_charge_capacity *
+			acpi_battery_scale(battery) * 1000;
+		break;
+	case POWER_SUPPLY_PROP_CHARGE_NOW:
+	case POWER_SUPPLY_PROP_ENERGY_NOW:
+		val->intval = battery->capacity_now *
+				acpi_battery_scale(battery) * 1000;
+		break;
+	case POWER_SUPPLY_PROP_TEMP:
+		val->intval = battery->temp_now - 2730;	// dK -> dC
+		break;
+	case POWER_SUPPLY_PROP_MODEL_NAME:
+		val->strval = battery->device_name;
+		break;
+	case POWER_SUPPLY_PROP_MANUFACTURER:
+		val->strval = battery->manufacturer_name;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static enum power_supply_property sbs_ac_props[] = {
+	POWER_SUPPLY_PROP_ONLINE,
+};
+
+static enum power_supply_property sbs_charge_battery_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_CURRENT_AVG,
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+	POWER_SUPPLY_PROP_CHARGE_FULL,
+	POWER_SUPPLY_PROP_CHARGE_NOW,
+	POWER_SUPPLY_PROP_TEMP,
+	POWER_SUPPLY_PROP_MODEL_NAME,
+	POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+static enum power_supply_property sbs_energy_battery_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_CURRENT_AVG,
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
+	POWER_SUPPLY_PROP_ENERGY_FULL,
+	POWER_SUPPLY_PROP_ENERGY_NOW,
+	POWER_SUPPLY_PROP_TEMP,
+	POWER_SUPPLY_PROP_MODEL_NAME,
+	POWER_SUPPLY_PROP_MANUFACTURER,
+};
+#endif
+
 /* --------------------------------------------------------------------------
                             Smart Battery System Management
    -------------------------------------------------------------------------- */
@@ -204,7 +343,7 @@ static int acpi_manager_get_info(struct acpi_sbs *sbs)
 	u16 battery_system_info;
 
 	result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_MANAGER,
-				 0x04, (u8 *) & battery_system_info);
+				 0x04, (u8 *)&battery_system_info);
 	if (!result)
 		sbs->batteries_supported = battery_system_info & 0x000f;
 	return result;
@@ -215,9 +354,12 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 	int i, result = 0;
 
 	for (i = 0; i < ARRAY_SIZE(info_readers); ++i) {
-		result = acpi_smbus_read(battery->sbs->hc, info_readers[i].mode,
-				    ACPI_SBS_BATTERY, info_readers[i].command,
-				    (u8 *) battery + info_readers[i].offset);
+		result = acpi_smbus_read(battery->sbs->hc,
+					 info_readers[i].mode,
+					 ACPI_SBS_BATTERY,
+					 info_readers[i].command,
+					 (u8 *) battery +
+						info_readers[i].offset);
 		if (result)
 			break;
 	}
@@ -228,7 +370,8 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 {
 	int i, result = 0;
 
-	if (time_before(jiffies, battery->update_time +
+	if (battery->update_time &&
+	    time_before(jiffies, battery->update_time +
 				msecs_to_jiffies(cache_time)))
 		return 0;
 	for (i = 0; i < ARRAY_SIZE(state_readers); ++i) {
@@ -250,26 +393,36 @@ static int acpi_battery_get_alarm(struct acpi_battery *battery)
 {
 	return acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
 				 ACPI_SBS_BATTERY, 0x01,
-				 (u8 *) & battery->alarm_capacity);
+				 (u8 *)&battery->alarm_capacity);
 }
 
 static int acpi_battery_set_alarm(struct acpi_battery *battery)
 {
 	struct acpi_sbs *sbs = battery->sbs;
-	u16 value;
-	return 0;
+	u16 value, sel = 1 << (battery->id + 12);
+
+	int ret;
+
 
 	if (sbs->manager_present) {
-		acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_MANAGER,
+		ret = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_MANAGER,
 				0x01, (u8 *)&value);
-		value &= 0x0fff;
-		value |= 1 << (battery->id + 12);
-		acpi_smbus_write(sbs->hc, SMBUS_WRITE_WORD, ACPI_SBS_MANAGER,
-				0x01, (u8 *)&value, 2);
+		if (ret)
+			goto end;
+		if ((value & 0xf000) != sel) {
+			value &= 0x0fff;
+			value |= sel;
+		ret = acpi_smbus_write(sbs->hc, SMBUS_WRITE_WORD,
+					 ACPI_SBS_MANAGER,
+					 0x01, (u8 *)&value, 2);
+		if (ret)
+			goto end;
+		}
 	}
-	value = battery->alarm_capacity / (acpi_battery_mode(battery) ? 10 : 1);
-	return acpi_smbus_write(sbs->hc, SMBUS_WRITE_WORD, ACPI_SBS_BATTERY,
-				0x01, (u8 *)&value, 2);
+	ret = acpi_smbus_write(sbs->hc, SMBUS_WRITE_WORD, ACPI_SBS_BATTERY,
+				0x01, (u8 *)&battery->alarm_capacity, 2);
+      end:
+	return ret;
 }
 
 static int acpi_ac_get_present(struct acpi_sbs *sbs)
@@ -289,22 +442,19 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)
    -------------------------------------------------------------------------- */
 
 /* Generic Routines */
-
 static int
 acpi_sbs_add_fs(struct proc_dir_entry **dir,
-			struct proc_dir_entry *parent_dir,
-			char *dir_name,
-			struct file_operations *info_fops,
-			struct file_operations *state_fops,
-			struct file_operations *alarm_fops, void *data)
+		struct proc_dir_entry *parent_dir,
+		char *dir_name,
+		struct file_operations *info_fops,
+		struct file_operations *state_fops,
+		struct file_operations *alarm_fops, void *data)
 {
 	struct proc_dir_entry *entry = NULL;
 
 	if (!*dir) {
 		*dir = proc_mkdir(dir_name, parent_dir);
 		if (!*dir) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"proc_mkdir() failed"));
 			return -ENODEV;
 		}
 		(*dir)->owner = THIS_MODULE;
@@ -313,10 +463,7 @@ acpi_sbs_add_fs(struct proc_dir_entry **dir,
 	/* 'info' [R] */
 	if (info_fops) {
 		entry = create_proc_entry(ACPI_SBS_FILE_INFO, S_IRUGO, *dir);
-		if (!entry) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"create_proc_entry() failed"));
-		} else {
+		if (entry) {
 			entry->proc_fops = info_fops;
 			entry->data = data;
 			entry->owner = THIS_MODULE;
@@ -326,10 +473,7 @@ acpi_sbs_add_fs(struct proc_dir_entry **dir,
 	/* 'state' [R] */
 	if (state_fops) {
 		entry = create_proc_entry(ACPI_SBS_FILE_STATE, S_IRUGO, *dir);
-		if (!entry) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"create_proc_entry() failed"));
-		} else {
+		if (entry) {
 			entry->proc_fops = state_fops;
 			entry->data = data;
 			entry->owner = THIS_MODULE;
@@ -339,16 +483,12 @@ acpi_sbs_add_fs(struct proc_dir_entry **dir,
 	/* 'alarm' [R/W] */
 	if (alarm_fops) {
 		entry = create_proc_entry(ACPI_SBS_FILE_ALARM, S_IRUGO, *dir);
-		if (!entry) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"create_proc_entry() failed"));
-		} else {
+		if (entry) {
 			entry->proc_fops = alarm_fops;
 			entry->data = data;
 			entry->owner = THIS_MODULE;
 		}
 	}
-
 	return 0;
 }
 
@@ -356,7 +496,6 @@ static void
 acpi_sbs_remove_fs(struct proc_dir_entry **dir,
 			   struct proc_dir_entry *parent_dir)
 {
-
 	if (*dir) {
 		remove_proc_entry(ACPI_SBS_FILE_INFO, *dir);
 		remove_proc_entry(ACPI_SBS_FILE_STATE, *dir);
@@ -364,11 +503,9 @@ acpi_sbs_remove_fs(struct proc_dir_entry **dir,
 		remove_proc_entry((*dir)->name, parent_dir);
 		*dir = NULL;
 	}
-
 }
 
 /* Smart Battery Interface */
-
 static struct proc_dir_entry *acpi_battery_dir = NULL;
 
 static inline char *acpi_battery_units(struct acpi_battery *battery)
@@ -506,7 +643,8 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer,
 		goto end;
 	}
 	alarm_string[count] = 0;
-	battery->alarm_capacity = simple_strtoul(alarm_string, NULL, 0);
+	battery->alarm_capacity = simple_strtoul(alarm_string, NULL, 0) /
+					acpi_battery_scale(battery);
 	acpi_battery_set_alarm(battery);
       end:
 	mutex_unlock(&sbs->lock);
@@ -579,9 +717,6 @@ static struct file_operations acpi_ac_state_fops = {
 /* --------------------------------------------------------------------------
                                  Driver Interface
    -------------------------------------------------------------------------- */
-
-/* Smart Battery */
-
 static int acpi_battery_read(struct acpi_battery *battery)
 {
 	int result = 0, saved_present = battery->present;
@@ -611,13 +746,14 @@ static int acpi_battery_read(struct acpi_battery *battery)
 	return result;
 }
 
+/* Smart Battery */
 static int acpi_battery_add(struct acpi_sbs *sbs, int id)
 {
-	int result;
 	struct acpi_battery *battery = &sbs->battery[id];
+	int result;
+
 	battery->id = id;
 	battery->sbs = sbs;
-	battery->update_time = 0;
 	result = acpi_battery_read(battery);
 	if (result)
 		return result;
@@ -627,6 +763,21 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
 			battery->name, &acpi_battery_info_fops,
 			&acpi_battery_state_fops, &acpi_battery_alarm_fops,
 			battery);
+#ifdef ENABLE_POWER_SUPPLY
+	battery->bat.name = battery->name;
+	battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
+	if (!acpi_battery_mode(battery)) {
+		battery->bat.properties = sbs_charge_battery_props;
+		battery->bat.num_properties =
+		    ARRAY_SIZE(sbs_charge_battery_props);
+	} else {
+		battery->bat.properties = sbs_energy_battery_props;
+		battery->bat.num_properties =
+		    ARRAY_SIZE(sbs_energy_battery_props);
+	}
+	battery->bat.get_property = acpi_sbs_battery_get_property;
+	result = power_supply_register(&sbs->device->dev, &battery->bat);
+#endif
 	printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",
 	       ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
 	       battery->name, sbs->battery->present ? "present" : "absent");
@@ -635,7 +786,10 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
 
 static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
 {
-
+#ifdef ENABLE_POWER_SUPPLY
+	if (sbs->battery[id].bat.dev)
+		power_supply_unregister(&sbs->battery[id].bat);
+#endif
 	if (sbs->battery[id].proc_entry) {
 		acpi_sbs_remove_fs(&(sbs->battery[id].proc_entry),
 				   acpi_battery_dir);
@@ -654,6 +808,14 @@ static int acpi_charger_add(struct acpi_sbs *sbs)
 				 &acpi_ac_state_fops, NULL, sbs);
 	if (result)
 		goto end;
+#ifdef ENABLE_POWER_SUPPLY
+	sbs->charger.name = "sbs-charger";
+	sbs->charger.type = POWER_SUPPLY_TYPE_MAINS;
+	sbs->charger.properties = sbs_ac_props;
+	sbs->charger.num_properties = ARRAY_SIZE(sbs_ac_props);
+	sbs->charger.get_property = sbs_get_ac_property;
+	power_supply_register(&sbs->device->dev, &sbs->charger);
+#endif
 	printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",
 	       ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
 	       ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line");
@@ -663,7 +825,10 @@ static int acpi_charger_add(struct acpi_sbs *sbs)
 
 static void acpi_charger_remove(struct acpi_sbs *sbs)
 {
-
+#ifdef ENABLE_POWER_SUPPLY
+	if (sbs->charger.dev)
+		power_supply_unregister(&sbs->charger);
+#endif
 	if (sbs->charger_entry)
 		acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir);
 }
@@ -680,6 +845,9 @@ void acpi_sbs_callback(void *context)
 		acpi_bus_generate_event4(ACPI_AC_CLASS, ACPI_AC_DIR_NAME,
 					 ACPI_SBS_NOTIFY_STATUS,
 					 sbs->charger_present);
+#ifdef ENABLE_POWER_SUPPLY
+		kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE);
+#endif
 	}
 	if (sbs->manager_present) {
 		for (id = 0; id < MAX_SBS_BAT; ++id) {
@@ -694,6 +862,9 @@ void acpi_sbs_callback(void *context)
 						bat->name,
 						ACPI_SBS_NOTIFY_STATUS,
 						bat->present);
+#ifdef ENABLE_POWER_SUPPLY
+			kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE);
+#endif
 		}
 	}
 }
@@ -782,45 +953,43 @@ static int acpi_sbs_resume(struct acpi_device *device)
 	return 0;
 }
 
+static struct acpi_driver acpi_sbs_driver = {
+	.name = "sbs",
+	.class = ACPI_SBS_CLASS,
+	.ids = sbs_device_ids,
+	.ops = {
+		.add = acpi_sbs_add,
+		.remove = acpi_sbs_remove,
+		.resume = acpi_sbs_resume,
+		},
+};
+
 static int __init acpi_sbs_init(void)
 {
 	int result = 0;
 
 	if (acpi_disabled)
 		return -ENODEV;
-
 	acpi_ac_dir = acpi_lock_ac_dir();
-	if (!acpi_ac_dir) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_lock_ac_dir() failed"));
+	if (!acpi_ac_dir)
 		return -ENODEV;
-	}
-
 	acpi_battery_dir = acpi_lock_battery_dir();
 	if (!acpi_battery_dir) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_lock_battery_dir() failed"));
 		acpi_sbs_rmdirs();
 		return -ENODEV;
 	}
-
 	result = acpi_bus_register_driver(&acpi_sbs_driver);
 	if (result < 0) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_bus_register_driver() failed"));
 		acpi_sbs_rmdirs();
 		return -ENODEV;
 	}
-
 	return 0;
 }
 
 static void __exit acpi_sbs_exit(void)
 {
 	acpi_bus_unregister_driver(&acpi_sbs_driver);
-
 	acpi_sbs_rmdirs();
-
 	return;
 }
 


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

* [PATCH 12/12] ACPI: SBS: Add ACPI_PROCFS around procfs handling code.
  2007-08-16 14:25 [PATCH 01/12] ACPI: AC: Add sysfs interface Alexey Starikovskiy
                   ` (9 preceding siblings ...)
  2007-08-16 14:27 ` [PATCH 11/12] ACPI: SBS: Add support for power_supply class (and sysfs) Alexey Starikovskiy
@ 2007-08-16 14:27 ` Alexey Starikovskiy
  2007-08-16 20:41   ` Alexey Starikovskiy
  10 siblings, 1 reply; 14+ messages in thread
From: Alexey Starikovskiy @ 2007-08-16 14:27 UTC (permalink / raw)
  To: lenb, linux-acpi; +Cc: astarikovskiy

From: Alexey Starikovskiy <aystarik@gmail.com>

Make procfs support optional under ACPI_PROCFS

Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
---

 drivers/acpi/sbs.c |   21 +++++++++++++++++++++
 1 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 87bee1e..7db85a9 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -29,9 +29,11 @@
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
 
+#ifdef CONFIG_ACPI_PROCFS
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <asm/uaccess.h>
+#endif
 
 #include <linux/acpi.h>
 #include <linux/timer.h>
@@ -91,7 +93,9 @@ struct acpi_battery {
 	struct power_supply bat;
 #endif
 	struct acpi_sbs *sbs;
+#ifdef CONFIG_ACPI_PROCFS
 	struct proc_dir_entry *proc_entry;
+#endif
 	unsigned long update_time;
 	char name[8];
 	char manufacturer_name[ACPI_SBS_BLOCK_MAX];
@@ -125,7 +129,9 @@ struct acpi_sbs {
 	struct acpi_device *device;
 	struct acpi_smb_hc *hc;
 	struct mutex lock;
+#ifdef CONFIG_ACPI_PROCFS
 	struct proc_dir_entry *charger_entry;
+#endif
 	struct acpi_battery battery[MAX_SBS_BAT];
 	u8 batteries_supported:4;
 	u8 manager_present:1;
@@ -389,6 +395,8 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 	return result;
 }
 
+#ifdef CONFIG_ACPI_PROCFS
+
 static int acpi_battery_get_alarm(struct acpi_battery *battery)
 {
 	return acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
@@ -424,6 +432,7 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery)
       end:
 	return ret;
 }
+#endif
 
 static int acpi_ac_get_present(struct acpi_sbs *sbs)
 {
@@ -759,10 +768,12 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
 		return result;
 
 	sprintf(battery->name, ACPI_BATTERY_DIR_NAME, id);
+#ifdef CONFIG_ACPI_PROCFS
 	acpi_sbs_add_fs(&battery->proc_entry, acpi_battery_dir,
 			battery->name, &acpi_battery_info_fops,
 			&acpi_battery_state_fops, &acpi_battery_alarm_fops,
 			battery);
+#endif
 #ifdef ENABLE_POWER_SUPPLY
 	battery->bat.name = battery->name;
 	battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
@@ -790,10 +801,12 @@ static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
 	if (sbs->battery[id].bat.dev)
 		power_supply_unregister(&sbs->battery[id].bat);
 #endif
+#ifdef CONFIG_ACPI_PROCFS
 	if (sbs->battery[id].proc_entry) {
 		acpi_sbs_remove_fs(&(sbs->battery[id].proc_entry),
 				   acpi_battery_dir);
 	}
+#endif
 }
 
 static int acpi_charger_add(struct acpi_sbs *sbs)
@@ -803,11 +816,13 @@ static int acpi_charger_add(struct acpi_sbs *sbs)
 	result = acpi_ac_get_present(sbs);
 	if (result)
 		goto end;
+#ifdef CONFIG_ACPI_PROCFS
 	result = acpi_sbs_add_fs(&sbs->charger_entry, acpi_ac_dir,
 				 ACPI_AC_DIR_NAME, NULL,
 				 &acpi_ac_state_fops, NULL, sbs);
 	if (result)
 		goto end;
+#endif
 #ifdef ENABLE_POWER_SUPPLY
 	sbs->charger.name = "sbs-charger";
 	sbs->charger.type = POWER_SUPPLY_TYPE_MAINS;
@@ -829,8 +844,10 @@ static void acpi_charger_remove(struct acpi_sbs *sbs)
 	if (sbs->charger.dev)
 		power_supply_unregister(&sbs->charger);
 #endif
+#ifdef CONFIG_ACPI_PROCFS
 	if (sbs->charger_entry)
 		acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir);
+#endif
 }
 
 void acpi_sbs_callback(void *context)
@@ -933,6 +950,7 @@ static int acpi_sbs_remove(struct acpi_device *device, int type)
 
 static void acpi_sbs_rmdirs(void)
 {
+#ifdef CONFIG_ACPI_PROCFS
 	if (acpi_ac_dir) {
 		acpi_unlock_ac_dir(acpi_ac_dir);
 		acpi_ac_dir = NULL;
@@ -941,6 +959,7 @@ static void acpi_sbs_rmdirs(void)
 		acpi_unlock_battery_dir(acpi_battery_dir);
 		acpi_battery_dir = NULL;
 	}
+#endif
 }
 
 static int acpi_sbs_resume(struct acpi_device *device)
@@ -970,6 +989,7 @@ static int __init acpi_sbs_init(void)
 
 	if (acpi_disabled)
 		return -ENODEV;
+#ifdef CONFIG_ACPI_PROCFS
 	acpi_ac_dir = acpi_lock_ac_dir();
 	if (!acpi_ac_dir)
 		return -ENODEV;
@@ -978,6 +998,7 @@ static int __init acpi_sbs_init(void)
 		acpi_sbs_rmdirs();
 		return -ENODEV;
 	}
+#endif
 	result = acpi_bus_register_driver(&acpi_sbs_driver);
 	if (result < 0) {
 		acpi_sbs_rmdirs();


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

* [PATCH 12/12] ACPI: SBS: Add ACPI_PROCFS around procfs handling code.
  2007-08-16 14:27 ` [PATCH 12/12] ACPI: SBS: Add ACPI_PROCFS around procfs handling code Alexey Starikovskiy
@ 2007-08-16 20:41   ` Alexey Starikovskiy
  0 siblings, 0 replies; 14+ messages in thread
From: Alexey Starikovskiy @ 2007-08-16 20:41 UTC (permalink / raw)
  To: Alexey Starikovskiy; +Cc: lenb, linux-acpi, astarikovskiy

Make procfs support optional under ACPI_PROCFS

Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
---

 drivers/acpi/sbs.c |   25 +++++++++++++++++++++++++
 1 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 87bee1e..abf7b94 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -29,9 +29,11 @@
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
 
+#ifdef CONFIG_ACPI_PROCFS
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <asm/uaccess.h>
+#endif
 
 #include <linux/acpi.h>
 #include <linux/timer.h>
@@ -91,7 +93,9 @@ struct acpi_battery {
 	struct power_supply bat;
 #endif
 	struct acpi_sbs *sbs;
+#ifdef CONFIG_ACPI_PROCFS
 	struct proc_dir_entry *proc_entry;
+#endif
 	unsigned long update_time;
 	char name[8];
 	char manufacturer_name[ACPI_SBS_BLOCK_MAX];
@@ -125,7 +129,9 @@ struct acpi_sbs {
 	struct acpi_device *device;
 	struct acpi_smb_hc *hc;
 	struct mutex lock;
+#ifdef CONFIG_ACPI_PROCFS
 	struct proc_dir_entry *charger_entry;
+#endif
 	struct acpi_battery battery[MAX_SBS_BAT];
 	u8 batteries_supported:4;
 	u8 manager_present:1;
@@ -389,6 +395,8 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 	return result;
 }
 
+#ifdef CONFIG_ACPI_PROCFS
+
 static int acpi_battery_get_alarm(struct acpi_battery *battery)
 {
 	return acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
@@ -425,6 +433,8 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery)
 	return ret;
 }
 
+#endif
+
 static int acpi_ac_get_present(struct acpi_sbs *sbs)
 {
 	int result;
@@ -441,6 +451,7 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)
                               FS Interface (/proc/acpi)
    -------------------------------------------------------------------------- */
 
+#ifdef CONFIG_ACPI_PROCFS
 /* Generic Routines */
 static int
 acpi_sbs_add_fs(struct proc_dir_entry **dir,
@@ -714,6 +725,8 @@ static struct file_operations acpi_ac_state_fops = {
 	.owner = THIS_MODULE,
 };
 
+#endif
+
 /* --------------------------------------------------------------------------
                                  Driver Interface
    -------------------------------------------------------------------------- */
@@ -759,10 +772,12 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
 		return result;
 
 	sprintf(battery->name, ACPI_BATTERY_DIR_NAME, id);
+#ifdef CONFIG_ACPI_PROCFS
 	acpi_sbs_add_fs(&battery->proc_entry, acpi_battery_dir,
 			battery->name, &acpi_battery_info_fops,
 			&acpi_battery_state_fops, &acpi_battery_alarm_fops,
 			battery);
+#endif
 #ifdef ENABLE_POWER_SUPPLY
 	battery->bat.name = battery->name;
 	battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
@@ -790,10 +805,12 @@ static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
 	if (sbs->battery[id].bat.dev)
 		power_supply_unregister(&sbs->battery[id].bat);
 #endif
+#ifdef CONFIG_ACPI_PROCFS
 	if (sbs->battery[id].proc_entry) {
 		acpi_sbs_remove_fs(&(sbs->battery[id].proc_entry),
 				   acpi_battery_dir);
 	}
+#endif
 }
 
 static int acpi_charger_add(struct acpi_sbs *sbs)
@@ -803,11 +820,13 @@ static int acpi_charger_add(struct acpi_sbs *sbs)
 	result = acpi_ac_get_present(sbs);
 	if (result)
 		goto end;
+#ifdef CONFIG_ACPI_PROCFS
 	result = acpi_sbs_add_fs(&sbs->charger_entry, acpi_ac_dir,
 				 ACPI_AC_DIR_NAME, NULL,
 				 &acpi_ac_state_fops, NULL, sbs);
 	if (result)
 		goto end;
+#endif
 #ifdef ENABLE_POWER_SUPPLY
 	sbs->charger.name = "sbs-charger";
 	sbs->charger.type = POWER_SUPPLY_TYPE_MAINS;
@@ -829,8 +848,10 @@ static void acpi_charger_remove(struct acpi_sbs *sbs)
 	if (sbs->charger.dev)
 		power_supply_unregister(&sbs->charger);
 #endif
+#ifdef CONFIG_ACPI_PROCFS
 	if (sbs->charger_entry)
 		acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir);
+#endif
 }
 
 void acpi_sbs_callback(void *context)
@@ -933,6 +954,7 @@ static int acpi_sbs_remove(struct acpi_device *device, int type)
 
 static void acpi_sbs_rmdirs(void)
 {
+#ifdef CONFIG_ACPI_PROCFS
 	if (acpi_ac_dir) {
 		acpi_unlock_ac_dir(acpi_ac_dir);
 		acpi_ac_dir = NULL;
@@ -941,6 +963,7 @@ static void acpi_sbs_rmdirs(void)
 		acpi_unlock_battery_dir(acpi_battery_dir);
 		acpi_battery_dir = NULL;
 	}
+#endif
 }
 
 static int acpi_sbs_resume(struct acpi_device *device)
@@ -970,6 +993,7 @@ static int __init acpi_sbs_init(void)
 
 	if (acpi_disabled)
 		return -ENODEV;
+#ifdef CONFIG_ACPI_PROCFS
 	acpi_ac_dir = acpi_lock_ac_dir();
 	if (!acpi_ac_dir)
 		return -ENODEV;
@@ -978,6 +1002,7 @@ static int __init acpi_sbs_init(void)
 		acpi_sbs_rmdirs();
 		return -ENODEV;
 	}
+#endif
 	result = acpi_bus_register_driver(&acpi_sbs_driver);
 	if (result < 0) {
 		acpi_sbs_rmdirs();


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

end of thread, other threads:[~2007-08-16 20:41 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-16 14:25 [PATCH 01/12] ACPI: AC: Add sysfs interface Alexey Starikovskiy
2007-08-16 14:26 ` [PATCH 02/12] ACPI: Battery: don't use acpi_extract_package() Alexey Starikovskiy
2007-08-16 14:26 ` [PATCH 03/12] ACPI: Battery: simplify update scheme Alexey Starikovskiy
2007-08-16 14:26 ` [PATCH 04/12] ACPI: Battery: Misc clean-ups, no functional changes Alexey Starikovskiy
2007-08-16 14:26 ` [PATCH 05/12] ACPI: Battery: Add sysfs support Alexey Starikovskiy
2007-08-16 14:26 ` [PATCH 06/12] ACPI: Add acpi_bus_generate_event4() function Alexey Starikovskiy
2007-08-16 14:26 ` [PATCH 07/12] ACPI: EC: Add new query handler to list head Alexey Starikovskiy
2007-08-16 14:26 ` [PATCH 08/12] ACPI: SBS: Split host controller (ACPI0001) from SBS driver (ACPI0002) Alexey Starikovskiy
2007-08-16 14:26 ` [PATCH 09/12] ACPI: SBS: Simplify data structures in SBS Alexey Starikovskiy
2007-08-16 14:26 ` [PATCH 10/12] ACPI: SBS: Make SBS reads table-driven Alexey Starikovskiy
2007-08-16 14:27 ` [PATCH 11/12] ACPI: SBS: Add support for power_supply class (and sysfs) Alexey Starikovskiy
2007-08-16 14:27 ` [PATCH 12/12] ACPI: SBS: Add ACPI_PROCFS around procfs handling code Alexey Starikovskiy
2007-08-16 20:41   ` Alexey Starikovskiy
  -- strict thread matches above, loose matches on Subject: below --
2007-08-16 14:03 [PATCH 01/12] ACPI: AC: Add sysfs interface Alexey Starikovskiy
2007-08-16 14:04 ` [PATCH 12/12] ACPI: SBS: Add ACPI_PROCFS around procfs handling code Alexey Starikovskiy

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.