All of lore.kernel.org
 help / color / mirror / Atom feed
* ACPI patches for 2.6.22 merge window
@ 2007-04-29  4:50 Len Brown
       [not found] ` <11778223068-git-send-email-len.brown@intel.com>
  2007-05-01  2:19 ` ACPI patches for 2.6.22 merge window Mattia Dongili
  0 siblings, 2 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi

I'm sending this batch upstream.
If you see anything wrong, please speak up.

If I've missed something that you think is appropriate
for 2.6.22 (I'm sure there are several) please let me know.

thanks,
-Len

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

* [PATCH 002/105] ACPI: EC: Don't use Global Lock if not asked to do so
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Alexey Starikovskiy, Len Brown

From: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>

Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/ec.c |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index a802962..7828ac5 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -827,7 +827,6 @@ acpi_fake_ecdt_callback(acpi_handle handle,
 	status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->gpe);
 	if (ACPI_FAILURE(status))
 		return status;
-	ec_ecdt->global_lock = TRUE;
 	ec_ecdt->handle = handle;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx",
@@ -901,8 +900,6 @@ static int __init acpi_ec_get_real_ecdt(void)
 	ec_ecdt->command_addr = ecdt_ptr->control.address;
 	ec_ecdt->data_addr = ecdt_ptr->data.address;
 	ec_ecdt->gpe = ecdt_ptr->gpe;
-	/* use the GL just to be safe */
-	ec_ecdt->global_lock = TRUE;
 	ec_ecdt->uid = ecdt_ptr->uid;
 
 	status = acpi_get_handle(NULL, ecdt_ptr->id, &ec_ecdt->handle);
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 003/105] ACPI: EC: Make EC to initialize first in ACPI
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Alexey Starikovskiy, Len Brown

From: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>

Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/Makefile |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 5956e9f..9623aac 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -1,6 +1,6 @@
 #
 # Makefile for the Linux ACPI interpreter
-# 
+#
 
 export ACPI_CFLAGS
 
@@ -32,16 +32,17 @@ obj-y				+= osl.o utils.o \
 processor-objs	+= processor_core.o processor_throttling.o \
 				processor_idle.o processor_thermal.o
 ifdef CONFIG_CPU_FREQ
-processor-objs	+= processor_perflib.o			
+processor-objs	+= processor_perflib.o
 endif
 
 obj-y				+= sleep/
 obj-y				+= bus.o glue.o
 obj-y				+= scan.o
+# Keep EC driver first. Initialization of others depend on it.
+obj-$(CONFIG_ACPI_EC)		+= ec.o
 obj-$(CONFIG_ACPI_AC) 		+= ac.o
 obj-$(CONFIG_ACPI_BATTERY)	+= battery.o
 obj-$(CONFIG_ACPI_BUTTON)	+= button.o
-obj-$(CONFIG_ACPI_EC)		+= ec.o
 obj-$(CONFIG_ACPI_FAN)		+= fan.o
 obj-$(CONFIG_ACPI_DOCK)		+= dock.o
 obj-$(CONFIG_ACPI_BAY)		+= bay.o
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 004/105] ACPI: EC: "Fake ECDT" workaround is not needed any longer.
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Alexey Starikovskiy, Len Brown

From: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>

Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/ec.c |   81 -----------------------------------------------------
 1 files changed, 0 insertions(+), 81 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 7828ac5..5999abd 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -805,74 +805,6 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
 	return 0;
 }
 
-static acpi_status __init
-acpi_fake_ecdt_callback(acpi_handle handle,
-			u32 Level, void *context, void **retval)
-{
-	acpi_status status;
-
-	mutex_init(&ec_ecdt->lock);
-	atomic_set(&ec_ecdt->event_count, 1);
-	if (acpi_ec_mode == EC_INTR) {
-		init_waitqueue_head(&ec_ecdt->wait);
-	}
-	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
-				     acpi_ec_io_ports, ec_ecdt);
-	if (ACPI_FAILURE(status))
-		return status;
-
-	ec_ecdt->uid = -1;
-	acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid);
-
-	status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->gpe);
-	if (ACPI_FAILURE(status))
-		return status;
-	ec_ecdt->handle = handle;
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx",
-			  ec_ecdt->gpe, ec_ecdt->command_addr,
-			  ec_ecdt->data_addr));
-
-	return AE_CTRL_TERMINATE;
-}
-
-/*
- * Some BIOS (such as some from Gateway laptops) access EC region very early
- * such as in BAT0._INI or EC._INI before an EC device is found and
- * do not provide an ECDT. According to ACPI spec, ECDT isn't mandatorily
- * required, but if EC regison is accessed early, it is required.
- * The routine tries to workaround the BIOS bug by pre-scan EC device
- * It assumes that _CRS, _HID, _GPE, _UID methods of EC don't touch any
- * op region (since _REG isn't invoked yet). The assumption is true for
- * all systems found.
- */
-static int __init acpi_ec_fake_ecdt(void)
-{
-	acpi_status status;
-	int ret = 0;
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Try to make an fake ECDT"));
-
-	ec_ecdt = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
-	if (!ec_ecdt) {
-		ret = -ENOMEM;
-		goto error;
-	}
-
-	status = acpi_get_devices(ACPI_EC_HID,
-				  acpi_fake_ecdt_callback, NULL, NULL);
-	if (ACPI_FAILURE(status)) {
-		kfree(ec_ecdt);
-		ec_ecdt = NULL;
-		ret = -ENODEV;
-		ACPI_EXCEPTION((AE_INFO, status, "Can't make an fake ECDT"));
-		goto error;
-	}
-	return 0;
-      error:
-	return ret;
-}
-
 static int __init acpi_ec_get_real_ecdt(void)
 {
 	acpi_status status;
@@ -916,18 +848,12 @@ static int __init acpi_ec_get_real_ecdt(void)
 	return -ENODEV;
 }
 
-static int __initdata acpi_fake_ecdt_enabled;
 int __init acpi_ec_ecdt_probe(void)
 {
 	acpi_status status;
 	int ret;
 
 	ret = acpi_ec_get_real_ecdt();
-	/* Try to make a fake ECDT */
-	if (ret && acpi_fake_ecdt_enabled) {
-		ret = acpi_ec_fake_ecdt();
-	}
-
 	if (ret)
 		return 0;
 
@@ -1000,13 +926,6 @@ static void __exit acpi_ec_exit(void)
 }
 #endif				/* 0 */
 
-static int __init acpi_fake_ecdt_setup(char *str)
-{
-	acpi_fake_ecdt_enabled = 1;
-	return 1;
-}
-
-__setup("acpi_fake_ecdt", acpi_fake_ecdt_setup);
 static int __init acpi_ec_set_intr_mode(char *str)
 {
 	int intr;
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 005/105] ACPI: EC: enable burst functionality in EC.
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Alexey Starikovskiy, Len Brown

From: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>

Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/ec.c |   89 ++++++++++++++++++++++-------------------------------
 1 files changed, 37 insertions(+), 52 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 5999abd..e7ce6e4 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -101,7 +101,6 @@ static struct acpi_ec {
 	struct mutex lock;
 	atomic_t query_pending;
 	atomic_t event_count;
-	atomic_t leaving_burst;	/* 0 : No, 1 : Yes, 2: abort */
 	wait_queue_head_t wait;
 } *ec_ecdt;
 
@@ -173,56 +172,6 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, unsigned count)
 	return -ETIME;
 }
 
-#ifdef ACPI_FUTURE_USAGE
-/*
- * Note: samsung nv5000 doesn't work with ec burst mode.
- * http://bugzilla.kernel.org/show_bug.cgi?id=4980
- */
-int acpi_ec_enter_burst_mode(struct acpi_ec *ec)
-{
-	u8 tmp = 0;
-	u8 status = 0;
-
-	status = acpi_ec_read_status(ec);
-	if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) {
-		status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
-		if (status)
-			goto end;
-		acpi_ec_write_cmd(ec, ACPI_EC_BURST_ENABLE);
-		status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1);
-		tmp = acpi_ec_read_data(ec);
-		if (tmp != 0x90) {	/* Burst ACK byte */
-			return -EINVAL;
-		}
-	}
-
-	atomic_set(&ec->leaving_burst, 0);
-	return 0;
-      end:
-	ACPI_EXCEPTION((AE_INFO, status, "EC wait, burst mode"));
-	return -1;
-}
-
-int acpi_ec_leave_burst_mode(struct acpi_ec *ec)
-{
-	u8 status = 0;
-
-	status = acpi_ec_read_status(ec);
-	if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)) {
-		status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
-		if (status)
-			goto end;
-		acpi_ec_write_cmd(ec, ACPI_EC_BURST_DISABLE);
-		acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
-	}
-	atomic_set(&ec->leaving_burst, 1);
-	return 0;
-      end:
-	ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode"));
-	return -1;
-}
-#endif				/* ACPI_FUTURE_USAGE */
-
 static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
 					const u8 * wdata, unsigned wdata_len,
 					u8 * rdata, unsigned rdata_len)
@@ -312,6 +261,21 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
 	return status;
 }
 
+/*
+ * Note: samsung nv5000 doesn't work with ec burst mode.
+ * http://bugzilla.kernel.org/show_bug.cgi?id=4980
+ */
+int acpi_ec_burst_enable(struct acpi_ec *ec)
+{
+	u8 d;
+	return acpi_ec_transaction(ec, ACPI_EC_BURST_ENABLE, NULL, 0, &d, 1);
+}
+
+int acpi_ec_burst_disable(struct acpi_ec *ec)
+{
+	return acpi_ec_transaction(ec, ACPI_EC_BURST_DISABLE, NULL, 0, NULL, 0);
+}
+
 static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data)
 {
 	int result;
@@ -333,6 +297,28 @@ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
 /*
  * Externally callable EC access functions. For now, assume 1 EC only
  */
+int ec_burst_enable(void)
+{
+	struct acpi_ec *ec;
+	if (!first_ec)
+		return -ENODEV;
+	ec = acpi_driver_data(first_ec);
+	return acpi_ec_burst_enable(ec);
+}
+
+EXPORT_SYMBOL(ec_burst_enable);
+
+int ec_burst_disable(void)
+{
+	struct acpi_ec *ec;
+	if (!first_ec)
+		return -ENODEV;
+	ec = acpi_driver_data(first_ec);
+	return acpi_ec_burst_disable(ec);
+}
+
+EXPORT_SYMBOL(ec_burst_disable);
+
 int ec_read(u8 addr, u8 * val)
 {
 	struct acpi_ec *ec;
@@ -639,7 +625,6 @@ static int acpi_ec_add(struct acpi_device *device)
 	atomic_set(&ec->query_pending, 0);
 	atomic_set(&ec->event_count, 1);
 	if (acpi_ec_mode == EC_INTR) {
-		atomic_set(&ec->leaving_burst, 1);
 		init_waitqueue_head(&ec->wait);
 	}
 	strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 006/105] ACPI: EC: Remove casts to/from void* from ec.c
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Alexey Starikovskiy, Len Brown

From: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>

Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/ec.c |   13 ++++++-------
 1 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index e7ce6e4..1989631 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -406,7 +406,7 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
 
 static void acpi_ec_gpe_query(void *ec_cxt)
 {
-	struct acpi_ec *ec = (struct acpi_ec *)ec_cxt;
+	struct acpi_ec *ec = ec_cxt;
 	u8 value = 0;
 	char object_name[8];
 
@@ -424,8 +424,9 @@ static u32 acpi_ec_gpe_handler(void *data)
 {
 	acpi_status status = AE_OK;
 	u8 value;
-	struct acpi_ec *ec = (struct acpi_ec *)data;
+	struct acpi_ec *ec = data;
 	atomic_inc(&ec->event_count);
+
 	if (acpi_ec_mode == EC_INTR) {
 		wake_up(&ec->wait);
 	}
@@ -468,7 +469,7 @@ acpi_ec_space_handler(u32 function,
 		      void *handler_context, void *region_context)
 {
 	int result = 0;
-	struct acpi_ec *ec = NULL;
+	struct acpi_ec *ec = handler_context;
 	u64 temp = *value;
 	acpi_integer f_v = 0;
 	int i = 0;
@@ -480,8 +481,6 @@ acpi_ec_space_handler(u32 function,
 		return AE_BAD_PARAMETER;
 	}
 
-	ec = (struct acpi_ec *)handler_context;
-
       next_byte:
 	switch (function) {
 	case ACPI_READ:
@@ -537,7 +536,7 @@ static struct proc_dir_entry *acpi_ec_dir;
 
 static int acpi_ec_read_info(struct seq_file *seq, void *offset)
 {
-	struct acpi_ec *ec = (struct acpi_ec *)seq->private;
+	struct acpi_ec *ec = seq->private;
 
 	if (!ec)
 		goto end;
@@ -694,7 +693,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
 static acpi_status
 acpi_ec_io_ports(struct acpi_resource *resource, void *context)
 {
-	struct acpi_ec *ec = (struct acpi_ec *)context;
+	struct acpi_ec *ec = context;
 
 	if (resource->type != ACPI_RESOURCE_TYPE_IO) {
 		return AE_OK;
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 007/105] ACPI: EC: Put install handlers into separate function.
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Alexey Starikovskiy, Len Brown

From: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>

Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/ec.c |   87 ++++++++++++++++------------------------------------
 1 files changed, 27 insertions(+), 60 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 1989631..399cedf 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -715,6 +715,28 @@ acpi_ec_io_ports(struct acpi_resource *resource, void *context)
 	return AE_OK;
 }
 
+static int ec_install_handlers(struct acpi_ec *ec)
+{
+	acpi_status status = acpi_install_gpe_handler(NULL, ec->gpe,
+						      ACPI_GPE_EDGE_TRIGGERED,
+						      &acpi_ec_gpe_handler, ec);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+	acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME);
+	acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+
+	status = acpi_install_address_space_handler(ec->handle,
+						    ACPI_ADR_SPACE_EC,
+						    &acpi_ec_space_handler,
+						    &acpi_ec_space_setup, ec);
+	if (ACPI_FAILURE(status)) {
+		acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
 static int acpi_ec_start(struct acpi_device *device)
 {
 	acpi_status status = AE_OK;
@@ -742,28 +764,7 @@ static int acpi_ec_start(struct acpi_device *device)
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx",
 			  ec->gpe, ec->command_addr, ec->data_addr));
 
-	/*
-	 * Install GPE handler
-	 */
-	status = acpi_install_gpe_handler(NULL, ec->gpe,
-					  ACPI_GPE_EDGE_TRIGGERED,
-					  &acpi_ec_gpe_handler, ec);
-	if (ACPI_FAILURE(status)) {
-		return -ENODEV;
-	}
-	acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME);
-	acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
-
-	status = acpi_install_address_space_handler(ec->handle,
-						    ACPI_ADR_SPACE_EC,
-						    &acpi_ec_space_handler,
-						    &acpi_ec_space_setup, ec);
-	if (ACPI_FAILURE(status)) {
-		acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
-		return -ENODEV;
-	}
-
-	return AE_OK;
+	return ec_install_handlers(ec);
 }
 
 static int acpi_ec_stop(struct acpi_device *device, int type)
@@ -818,56 +819,22 @@ static int __init acpi_ec_get_real_ecdt(void)
 	ec_ecdt->gpe = ecdt_ptr->gpe;
 	ec_ecdt->uid = ecdt_ptr->uid;
 
-	status = acpi_get_handle(NULL, ecdt_ptr->id, &ec_ecdt->handle);
-	if (ACPI_FAILURE(status)) {
-		goto error;
-	}
-
+	ec_ecdt->handle = ACPI_ROOT_OBJECT;
 	return 0;
-      error:
-	ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT"));
-	kfree(ec_ecdt);
-	ec_ecdt = NULL;
-
-	return -ENODEV;
 }
 
 int __init acpi_ec_ecdt_probe(void)
 {
-	acpi_status status;
 	int ret;
 
 	ret = acpi_ec_get_real_ecdt();
 	if (ret)
 		return 0;
 
-	/*
-	 * Install GPE handler
-	 */
-	status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe,
-					  ACPI_GPE_EDGE_TRIGGERED,
-					  &acpi_ec_gpe_handler, ec_ecdt);
-	if (ACPI_FAILURE(status)) {
-		goto error;
-	}
-	acpi_set_gpe_type(NULL, ec_ecdt->gpe, ACPI_GPE_TYPE_RUNTIME);
-	acpi_enable_gpe(NULL, ec_ecdt->gpe, ACPI_NOT_ISR);
-
-	status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
-						    ACPI_ADR_SPACE_EC,
-						    &acpi_ec_space_handler,
-						    &acpi_ec_space_setup,
-						    ec_ecdt);
-	if (ACPI_FAILURE(status)) {
-		acpi_remove_gpe_handler(NULL, ec_ecdt->gpe,
-					&acpi_ec_gpe_handler);
-		goto error;
-	}
-
-	return 0;
+	ret = ec_install_handlers(ec_ecdt);
+	if (!ret)
+		return 0;
 
-      error:
-	ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT"));
 	kfree(ec_ecdt);
 	ec_ecdt = NULL;
 
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 008/105] ACPI: EC: Clean ECDT and namespace parsing.
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Alexey Starikovskiy, Len Brown

From: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>

Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/ec.c |  205 ++++++++++++++++++++++++++++-------------------------
 1 files changed, 109 insertions(+), 96 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 399cedf..c9dcf9a 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -604,74 +604,73 @@ static int acpi_ec_remove_fs(struct acpi_device *device)
 /* --------------------------------------------------------------------------
                                Driver Interface
    -------------------------------------------------------------------------- */
+static acpi_status
+ec_parse_io_ports(struct acpi_resource *resource, void *context);
+
+static acpi_status
+ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval);
+
+static struct acpi_ec *make_acpi_ec(void)
+{
+	struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
+	if (!ec)
+		return NULL;
+
+	atomic_set(&ec->query_pending, 0);
+	atomic_set(&ec->event_count, 1);
+	mutex_init(&ec->lock);
+	init_waitqueue_head(&ec->wait);
+
+	return ec;
+}
 
 static int acpi_ec_add(struct acpi_device *device)
 {
-	int result = 0;
 	acpi_status status = AE_OK;
 	struct acpi_ec *ec = NULL;
 
 	if (!device)
 		return -EINVAL;
 
-	ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
+	strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_EC_CLASS);
+
+	ec = make_acpi_ec();
 	if (!ec)
 		return -ENOMEM;
 
-	ec->handle = device->handle;
-	ec->uid = -1;
-	mutex_init(&ec->lock);
-	atomic_set(&ec->query_pending, 0);
-	atomic_set(&ec->event_count, 1);
-	if (acpi_ec_mode == EC_INTR) {
-		init_waitqueue_head(&ec->wait);
+	status = ec_parse_device(device->handle, 0, ec, NULL);
+	if (status != AE_CTRL_TERMINATE) {
+		kfree(ec);
+		return -EINVAL;
 	}
-	strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
-	strcpy(acpi_device_class(device), ACPI_EC_CLASS);
-	acpi_driver_data(device) = ec;
 
-	/* Use the global lock for all EC transactions? */
-	acpi_evaluate_integer(ec->handle, "_GLK", NULL, &ec->global_lock);
-
-	/* XXX we don't test uids, because on some boxes ecdt uid = 0, see:
-	   http://bugzilla.kernel.org/show_bug.cgi?id=6111 */
+	/* Check if we found the boot EC */
 	if (ec_ecdt) {
-		acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
-						  ACPI_ADR_SPACE_EC,
-						  &acpi_ec_space_handler);
+		if (ec_ecdt->gpe == ec->gpe) {
+			/* We might have incorrect info for GL at boot time */
+			mutex_lock(&ec_ecdt->lock);
+			ec_ecdt->global_lock = ec->global_lock;
+			mutex_unlock(&ec_ecdt->lock);
+			kfree(ec);
+			ec = ec_ecdt;
+		}
+	}
 
-		acpi_remove_gpe_handler(NULL, ec_ecdt->gpe,
-					&acpi_ec_gpe_handler);
+	ec->handle = device->handle;
 
-		kfree(ec_ecdt);
-	}
+	acpi_driver_data(device) = ec;
 
-	/* Get GPE bit assignment (EC events). */
-	/* TODO: Add support for _GPE returning a package */
-	status = acpi_evaluate_integer(ec->handle, "_GPE", NULL, &ec->gpe);
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status,
-				"Obtaining GPE bit assignment"));
-		result = -ENODEV;
-		goto end;
-	}
+	if (!first_ec)
+		first_ec = device;
 
-	result = acpi_ec_add_fs(device);
-	if (result)
-		goto end;
+	acpi_ec_add_fs(device);
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.",
 			  acpi_device_name(device), acpi_device_bid(device),
 			  (u32) ec->gpe));
 
-	if (!first_ec)
-		first_ec = device;
-
-      end:
-	if (result)
-		kfree(ec);
-
-	return result;
+	return 0;
 }
 
 static int acpi_ec_remove(struct acpi_device *device, int type)
@@ -685,13 +684,19 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
 
 	acpi_ec_remove_fs(device);
 
-	kfree(ec);
+	acpi_driver_data(device) = NULL;
+	if (device == first_ec)
+		first_ec = NULL;
+
+	/* Don't touch boot EC */
+	if (ec_ecdt != ec)
+		kfree(ec);
 
 	return 0;
 }
 
 static acpi_status
-acpi_ec_io_ports(struct acpi_resource *resource, void *context)
+ec_parse_io_ports(struct acpi_resource *resource, void *context)
 {
 	struct acpi_ec *ec = context;
 
@@ -717,9 +722,10 @@ acpi_ec_io_ports(struct acpi_resource *resource, void *context)
 
 static int ec_install_handlers(struct acpi_ec *ec)
 {
-	acpi_status status = acpi_install_gpe_handler(NULL, ec->gpe,
-						      ACPI_GPE_EDGE_TRIGGERED,
-						      &acpi_ec_gpe_handler, ec);
+	acpi_status status;
+	status = acpi_install_gpe_handler(NULL, ec->gpe,
+					  ACPI_GPE_EDGE_TRIGGERED,
+					  &acpi_ec_gpe_handler, ec);
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
 	acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME);
@@ -739,8 +745,7 @@ static int ec_install_handlers(struct acpi_ec *ec)
 
 static int acpi_ec_start(struct acpi_device *device)
 {
-	acpi_status status = AE_OK;
-	struct acpi_ec *ec = NULL;
+	struct acpi_ec *ec;
 
 	if (!device)
 		return -EINVAL;
@@ -750,32 +755,31 @@ static int acpi_ec_start(struct acpi_device *device)
 	if (!ec)
 		return -EINVAL;
 
-	/*
-	 * Get I/O port addresses. Convert to GAS format.
-	 */
-	status = acpi_walk_resources(ec->handle, METHOD_NAME__CRS,
-				     acpi_ec_io_ports, ec);
-	if (ACPI_FAILURE(status) || ec->command_addr == 0) {
-		ACPI_EXCEPTION((AE_INFO, status,
-				"Error getting I/O port addresses"));
-		return -ENODEV;
-	}
-
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx",
 			  ec->gpe, ec->command_addr, ec->data_addr));
 
+	/* Boot EC is already working */
+	if (ec == ec_ecdt)
+		return 0;
+
 	return ec_install_handlers(ec);
 }
 
 static int acpi_ec_stop(struct acpi_device *device, int type)
 {
-	acpi_status status = AE_OK;
-	struct acpi_ec *ec = NULL;
+	acpi_status status;
+	struct acpi_ec *ec;
 
 	if (!device)
 		return -EINVAL;
 
 	ec = acpi_driver_data(device);
+	if (!ec)
+		return -EINVAL;
+
+	/* Don't touch boot EC */
+	if (ec == ec_ecdt)
+		return 0;
 
 	status = acpi_remove_address_space_handler(ec->handle,
 						   ACPI_ADR_SPACE_EC,
@@ -790,51 +794,64 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
 	return 0;
 }
 
-static int __init acpi_ec_get_real_ecdt(void)
+static acpi_status
+ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
 {
 	acpi_status status;
+
+	struct acpi_ec *ec = context;
+	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
+				     ec_parse_io_ports, ec);
+	if (ACPI_FAILURE(status))
+		return status;
+
+	/* Get GPE bit assignment (EC events). */
+	/* TODO: Add support for _GPE returning a package */
+	status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
+	if (ACPI_FAILURE(status))
+		return status;
+
+	/* Use the global lock for all EC transactions? */
+	acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
+
+	ec->handle = handle;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx",
+			  ec->gpe, ec->command_addr, ec->data_addr));
+
+	return AE_CTRL_TERMINATE;
+}
+
+int __init acpi_ec_ecdt_probe(void)
+{
+	int ret;
+	acpi_status status;
 	struct acpi_table_ecdt *ecdt_ptr;
 
+	ec_ecdt = make_acpi_ec();
+	if (!ec_ecdt)
+		return -ENOMEM;
+	/*
+	 * Generate a boot ec context
+	 */
+
 	status = acpi_get_table(ACPI_SIG_ECDT, 1,
 				(struct acpi_table_header **)&ecdt_ptr);
 	if (ACPI_FAILURE(status))
-		return -ENODEV;
+		goto error;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found ECDT"));
 
-	/*
-	 * Generate a temporary ec context to use until the namespace is scanned
-	 */
-	ec_ecdt = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
-	if (!ec_ecdt)
-		return -ENOMEM;
-
-	mutex_init(&ec_ecdt->lock);
-	atomic_set(&ec_ecdt->event_count, 1);
-	if (acpi_ec_mode == EC_INTR) {
-		init_waitqueue_head(&ec_ecdt->wait);
-	}
 	ec_ecdt->command_addr = ecdt_ptr->control.address;
 	ec_ecdt->data_addr = ecdt_ptr->data.address;
 	ec_ecdt->gpe = ecdt_ptr->gpe;
 	ec_ecdt->uid = ecdt_ptr->uid;
-
 	ec_ecdt->handle = ACPI_ROOT_OBJECT;
-	return 0;
-}
-
-int __init acpi_ec_ecdt_probe(void)
-{
-	int ret;
-
-	ret = acpi_ec_get_real_ecdt();
-	if (ret)
-		return 0;
 
 	ret = ec_install_handlers(ec_ecdt);
 	if (!ret)
 		return 0;
-
+      error:
 	kfree(ec_ecdt);
 	ec_ecdt = NULL;
 
@@ -884,12 +901,8 @@ static int __init acpi_ec_set_intr_mode(char *str)
 	if (!get_option(&str, &intr))
 		return 0;
 
-	if (intr) {
-		acpi_ec_mode = EC_INTR;
-	} else {
-		acpi_ec_mode = EC_POLL;
-	}
-	acpi_ec_driver.ops.add = acpi_ec_add;
+	acpi_ec_mode = (intr) ? EC_INTR : EC_POLL;
+
 	printk(KERN_NOTICE PREFIX "%s mode.\n", intr ? "interrupt" : "polling");
 
 	return 1;
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 009/105] ACPI: EC: Rename ec_ecdt to more informative boot_ec
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Alexey Starikovskiy, Len Brown

From: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>

Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/ec.c |   43 ++++++++++++++++++++-----------------------
 1 files changed, 20 insertions(+), 23 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index c9dcf9a..1250468 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -102,7 +102,7 @@ static struct acpi_ec {
 	atomic_t query_pending;
 	atomic_t event_count;
 	wait_queue_head_t wait;
-} *ec_ecdt;
+} *boot_ec;
 
 /* External interfaces use first EC only, so remember */
 static struct acpi_device *first_ec;
@@ -646,21 +646,18 @@ static int acpi_ec_add(struct acpi_device *device)
 	}
 
 	/* Check if we found the boot EC */
-	if (ec_ecdt) {
-		if (ec_ecdt->gpe == ec->gpe) {
+	if (boot_ec) {
+		if (boot_ec->gpe == ec->gpe) {
 			/* We might have incorrect info for GL at boot time */
-			mutex_lock(&ec_ecdt->lock);
-			ec_ecdt->global_lock = ec->global_lock;
-			mutex_unlock(&ec_ecdt->lock);
+			mutex_lock(&boot_ec->lock);
+			boot_ec->global_lock = ec->global_lock;
+			mutex_unlock(&boot_ec->lock);
 			kfree(ec);
-			ec = ec_ecdt;
+			ec = boot_ec;
 		}
 	}
-
 	ec->handle = device->handle;
-
 	acpi_driver_data(device) = ec;
-
 	if (!first_ec)
 		first_ec = device;
 
@@ -689,7 +686,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
 		first_ec = NULL;
 
 	/* Don't touch boot EC */
-	if (ec_ecdt != ec)
+	if (boot_ec != ec)
 		kfree(ec);
 
 	return 0;
@@ -759,7 +756,7 @@ static int acpi_ec_start(struct acpi_device *device)
 			  ec->gpe, ec->command_addr, ec->data_addr));
 
 	/* Boot EC is already working */
-	if (ec == ec_ecdt)
+	if (ec == boot_ec)
 		return 0;
 
 	return ec_install_handlers(ec);
@@ -778,7 +775,7 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
 		return -EINVAL;
 
 	/* Don't touch boot EC */
-	if (ec == ec_ecdt)
+	if (ec == boot_ec)
 		return 0;
 
 	status = acpi_remove_address_space_handler(ec->handle,
@@ -828,8 +825,8 @@ int __init acpi_ec_ecdt_probe(void)
 	acpi_status status;
 	struct acpi_table_ecdt *ecdt_ptr;
 
-	ec_ecdt = make_acpi_ec();
-	if (!ec_ecdt)
+	boot_ec = make_acpi_ec();
+	if (!boot_ec)
 		return -ENOMEM;
 	/*
 	 * Generate a boot ec context
@@ -842,18 +839,18 @@ int __init acpi_ec_ecdt_probe(void)
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found ECDT"));
 
-	ec_ecdt->command_addr = ecdt_ptr->control.address;
-	ec_ecdt->data_addr = ecdt_ptr->data.address;
-	ec_ecdt->gpe = ecdt_ptr->gpe;
-	ec_ecdt->uid = ecdt_ptr->uid;
-	ec_ecdt->handle = ACPI_ROOT_OBJECT;
+	boot_ec->command_addr = ecdt_ptr->control.address;
+	boot_ec->data_addr = ecdt_ptr->data.address;
+	boot_ec->gpe = ecdt_ptr->gpe;
+	boot_ec->uid = ecdt_ptr->uid;
+	boot_ec->handle = ACPI_ROOT_OBJECT;
 
-	ret = ec_install_handlers(ec_ecdt);
+	ret = ec_install_handlers(boot_ec);
 	if (!ret)
 		return 0;
       error:
-	kfree(ec_ecdt);
-	ec_ecdt = NULL;
+	kfree(boot_ec);
+	boot_ec = NULL;
 
 	return -ENODEV;
 }
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 010/105] ACPI: EC: first_ec is better to be acpi_ec than acpi_device.
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Alexey Starikovskiy, Len Brown

From: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>

Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/ec.c |   41 +++++++++++++----------------------------
 1 files changed, 13 insertions(+), 28 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 1250468..187981a 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -91,6 +91,7 @@ static struct acpi_driver acpi_ec_driver = {
 };
 
 /* If we find an EC via the ECDT, we need to keep a ptr to its context */
+/* External interfaces use first EC only, so remember */
 static struct acpi_ec {
 	acpi_handle handle;
 	unsigned long uid;
@@ -102,10 +103,7 @@ static struct acpi_ec {
 	atomic_t query_pending;
 	atomic_t event_count;
 	wait_queue_head_t wait;
-} *boot_ec;
-
-/* External interfaces use first EC only, so remember */
-static struct acpi_device *first_ec;
+} *boot_ec, *first_ec;
 
 /* --------------------------------------------------------------------------
                              Transaction Management
@@ -299,38 +297,31 @@ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
  */
 int ec_burst_enable(void)
 {
-	struct acpi_ec *ec;
 	if (!first_ec)
 		return -ENODEV;
-	ec = acpi_driver_data(first_ec);
-	return acpi_ec_burst_enable(ec);
+	return acpi_ec_burst_enable(first_ec);
 }
 
 EXPORT_SYMBOL(ec_burst_enable);
 
 int ec_burst_disable(void)
 {
-	struct acpi_ec *ec;
 	if (!first_ec)
 		return -ENODEV;
-	ec = acpi_driver_data(first_ec);
-	return acpi_ec_burst_disable(ec);
+	return acpi_ec_burst_disable(first_ec);
 }
 
 EXPORT_SYMBOL(ec_burst_disable);
 
 int ec_read(u8 addr, u8 * val)
 {
-	struct acpi_ec *ec;
 	int err;
 	u8 temp_data;
 
 	if (!first_ec)
 		return -ENODEV;
 
-	ec = acpi_driver_data(first_ec);
-
-	err = acpi_ec_read(ec, addr, &temp_data);
+	err = acpi_ec_read(first_ec, addr, &temp_data);
 
 	if (!err) {
 		*val = temp_data;
@@ -343,15 +334,12 @@ EXPORT_SYMBOL(ec_read);
 
 int ec_write(u8 addr, u8 val)
 {
-	struct acpi_ec *ec;
 	int err;
 
 	if (!first_ec)
 		return -ENODEV;
 
-	ec = acpi_driver_data(first_ec);
-
-	err = acpi_ec_write(ec, addr, val);
+	err = acpi_ec_write(first_ec, addr, val);
 
 	return err;
 }
@@ -362,14 +350,10 @@ int ec_transaction(u8 command,
 		   const u8 * wdata, unsigned wdata_len,
 		   u8 * rdata, unsigned rdata_len)
 {
-	struct acpi_ec *ec;
-
 	if (!first_ec)
 		return -ENODEV;
 
-	ec = acpi_driver_data(first_ec);
-
-	return acpi_ec_transaction(ec, command, wdata,
+	return acpi_ec_transaction(first_ec, command, wdata,
 				   wdata_len, rdata, rdata_len);
 }
 
@@ -655,11 +639,10 @@ static int acpi_ec_add(struct acpi_device *device)
 			kfree(ec);
 			ec = boot_ec;
 		}
-	}
+	} else
+		first_ec = ec;
 	ec->handle = device->handle;
 	acpi_driver_data(device) = ec;
-	if (!first_ec)
-		first_ec = device;
 
 	acpi_ec_add_fs(device);
 
@@ -682,7 +665,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
 	acpi_ec_remove_fs(device);
 
 	acpi_driver_data(device) = NULL;
-	if (device == first_ec)
+	if (ec == first_ec)
 		first_ec = NULL;
 
 	/* Don't touch boot EC */
@@ -846,8 +829,10 @@ int __init acpi_ec_ecdt_probe(void)
 	boot_ec->handle = ACPI_ROOT_OBJECT;
 
 	ret = ec_install_handlers(boot_ec);
-	if (!ret)
+	if (!ret) {
+		first_ec = boot_ec;
 		return 0;
+	}
       error:
 	kfree(boot_ec);
 	boot_ec = NULL;
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 011/105] ACPI: EC: Cleanup of EC initialization
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Alexey Starikovskiy, Len Brown

From: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>

Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/ec.c |   32 +++++++++++++-------------------
 1 files changed, 13 insertions(+), 19 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 187981a..2a17229 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -1,6 +1,8 @@
 /*
- *  acpi_ec.c - ACPI Embedded Controller Driver ($Revision: 38 $)
+ *  ec.c - ACPI Embedded Controller Driver (v2.0)
  *
+ *  Copyright (C) 2006, 2007 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
+ *  Copyright (C) 2006 Denis Sadykov <denis.m.sadykov@intel.com>
  *  Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
@@ -94,7 +96,6 @@ static struct acpi_driver acpi_ec_driver = {
 /* External interfaces use first EC only, so remember */
 static struct acpi_ec {
 	acpi_handle handle;
-	unsigned long uid;
 	unsigned long gpe;
 	unsigned long command_addr;
 	unsigned long data_addr;
@@ -525,13 +526,11 @@ static int acpi_ec_read_info(struct seq_file *seq, void *offset)
 	if (!ec)
 		goto end;
 
-	seq_printf(seq, "gpe:                 0x%02x\n", (u32) ec->gpe);
-	seq_printf(seq, "ports:                   0x%02x, 0x%02x\n",
-		   (u32) ec->command_addr, (u32) ec->data_addr);
-	seq_printf(seq, "use global lock:         %s\n",
+	seq_printf(seq, "gpe:\t\t\t0x%02x\n", (u32) ec->gpe);
+	seq_printf(seq, "ports:\t\t\t0x%02x, 0x%02x\n",
+		   (unsigned)ec->command_addr, (unsigned)ec->data_addr);
+	seq_printf(seq, "use global lock:\t%s\n",
 		   ec->global_lock ? "yes" : "no");
-	acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
-
       end:
 	return 0;
 }
@@ -655,15 +654,13 @@ static int acpi_ec_add(struct acpi_device *device)
 
 static int acpi_ec_remove(struct acpi_device *device, int type)
 {
-	struct acpi_ec *ec = NULL;
+	struct acpi_ec *ec;
 
 	if (!device)
 		return -EINVAL;
 
 	ec = acpi_driver_data(device);
-
 	acpi_ec_remove_fs(device);
-
 	acpi_driver_data(device) = NULL;
 	if (ec == first_ec)
 		first_ec = NULL;
@@ -671,7 +668,6 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
 	/* Don't touch boot EC */
 	if (boot_ec != ec)
 		kfree(ec);
-
 	return 0;
 }
 
@@ -680,22 +676,20 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context)
 {
 	struct acpi_ec *ec = context;
 
-	if (resource->type != ACPI_RESOURCE_TYPE_IO) {
+	if (resource->type != ACPI_RESOURCE_TYPE_IO)
 		return AE_OK;
-	}
 
 	/*
 	 * The first address region returned is the data port, and
 	 * the second address region returned is the status/command
 	 * port.
 	 */
-	if (ec->data_addr == 0) {
+	if (ec->data_addr == 0)
 		ec->data_addr = resource->data.io.minimum;
-	} else if (ec->command_addr == 0) {
+	else if (ec->command_addr == 0)
 		ec->command_addr = resource->data.io.minimum;
-	} else {
+	else
 		return AE_CTRL_TERMINATE;
-	}
 
 	return AE_OK;
 }
@@ -708,6 +702,7 @@ static int ec_install_handlers(struct acpi_ec *ec)
 					  &acpi_ec_gpe_handler, ec);
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
+
 	acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME);
 	acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
 
@@ -825,7 +820,6 @@ int __init acpi_ec_ecdt_probe(void)
 	boot_ec->command_addr = ecdt_ptr->control.address;
 	boot_ec->data_addr = ecdt_ptr->data.address;
 	boot_ec->gpe = ecdt_ptr->gpe;
-	boot_ec->uid = ecdt_ptr->uid;
 	boot_ec->handle = ACPI_ROOT_OBJECT;
 
 	ret = ec_install_handlers(boot_ec);
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 012/105] ACPI: EC: Block queries until EC is fully initialized
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Alexey Starikovskiy, Len Brown

From: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>

Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/ec.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 2a17229..e08cf98 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -599,7 +599,7 @@ static struct acpi_ec *make_acpi_ec(void)
 	if (!ec)
 		return NULL;
 
-	atomic_set(&ec->query_pending, 0);
+	atomic_set(&ec->query_pending, 1);
 	atomic_set(&ec->event_count, 1);
 	mutex_init(&ec->lock);
 	init_waitqueue_head(&ec->wait);
@@ -715,6 +715,9 @@ static int ec_install_handlers(struct acpi_ec *ec)
 		return -ENODEV;
 	}
 
+	/* EC is fully operational, allow queries */
+	atomic_set(&ec->query_pending, 0);
+
 	return 0;
 }
 
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 013/105] asus-laptop: use acpi_evaluate_integer instead of read_acpi_int
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Corentin Chary, Len Brown

From: Corentin Chary <corentincj@iksaif.net>

Use acpi_evaluate_integer() instead of read_acpi_int()

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/asus-laptop.c |   68 ++++++++++++++++++++++----------------------
 1 files changed, 34 insertions(+), 34 deletions(-)

diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c
index 4b23212..dcab778 100644
--- a/drivers/misc/asus-laptop.c
+++ b/drivers/misc/asus-laptop.c
@@ -245,32 +245,19 @@ static int write_acpi_int(acpi_handle handle, const char *method, int val,
 	return (status == AE_OK);
 }
 
-static int read_acpi_int(acpi_handle handle, const char *method, int *val,
-			 struct acpi_object_list *params)
-{
-	struct acpi_buffer output;
-	union acpi_object out_obj;
-	acpi_status status;
-
-	output.length = sizeof(out_obj);
-	output.pointer = &out_obj;
-
-	status = acpi_evaluate_object(handle, (char *)method, params, &output);
-	*val = out_obj.integer.value;
-	return (status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER);
-}
-
 static int read_wireless_status(int mask)
 {
-	int status;
+	ulong status;
+	acpi_status rv = AE_OK;
 
 	if (!wireless_status_handle)
 		return (hotk->status & mask) ? 1 : 0;
 
-	if (read_acpi_int(wireless_status_handle, NULL, &status, NULL)) {
-		return (status & mask) ? 1 : 0;
-	} else
+	rv = acpi_evaluate_integer(wireless_status_handle, NULL, NULL, &status);
+	if (ACPI_FAILURE(rv))
 		printk(ASUS_WARNING "Error reading Wireless status\n");
+	else
+		return (status & mask) ? 1 : 0;
 
 	return (hotk->status & mask) ? 1 : 0;
 }
@@ -354,9 +341,11 @@ static void lcd_blank(int blank)
 
 static int read_brightness(struct backlight_device *bd)
 {
-	int value;
+	ulong value;
+	acpi_status rv = AE_OK;
 
-	if (!read_acpi_int(brightness_get_handle, NULL, &value, NULL))
+	rv = acpi_evaluate_integer(brightness_get_handle, NULL, NULL, &value);
+	if (ACPI_FAILURE(rv))
 		printk(ASUS_WARNING "Error reading brightness\n");
 
 	return value;
@@ -403,8 +392,10 @@ static ssize_t show_infos(struct device *dev,
 			  struct device_attribute *attr, char *page)
 {
 	int len = 0;
-	int temp;
+	ulong temp;
 	char buf[16];		//enough for all info
+	acpi_status rv = AE_OK;
+
 	/*
 	 * We use the easy way, we don't care of off and count, so we don't set eof
 	 * to 1
@@ -418,9 +409,10 @@ static ssize_t show_infos(struct device *dev,
 	 * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card.
 	 * The significance of others is yet to be found.
 	 */
-	if (read_acpi_int(hotk->handle, "SFUN", &temp, NULL))
-		len +=
-		    sprintf(page + len, "SFUN value         : 0x%04x\n", temp);
+	rv = acpi_evaluate_integer(hotk->handle, "SFUN", NULL, &temp);
+	if (!ACPI_FAILURE(rv))
+		len += sprintf(page + len, "SFUN value         : 0x%04x\n",
+			       (uint) temp);
 	/*
 	 * Another value for userspace: the ASYM method returns 0x02 for
 	 * battery low and 0x04 for battery critical, its readings tend to be
@@ -428,9 +420,10 @@ static ssize_t show_infos(struct device *dev,
 	 * Note: since not all the laptops provide this method, errors are
 	 * silently ignored.
 	 */
-	if (read_acpi_int(hotk->handle, "ASYM", &temp, NULL))
-		len +=
-		    sprintf(page + len, "ASYM value         : 0x%04x\n", temp);
+	rv = acpi_evaluate_integer(hotk->handle, "ASYM", NULL, &temp);
+	if (!ACPI_FAILURE(rv))
+		len += sprintf(page + len, "ASYM value         : 0x%04x\n",
+			       (uint) temp);
 	if (asus_info) {
 		snprintf(buf, 16, "%d", asus_info->length);
 		len += sprintf(page + len, "DSDT length        : %s\n", buf);
@@ -547,12 +540,15 @@ static void set_display(int value)
 
 static int read_display(void)
 {
-	int value = 0;
+	ulong value = 0;
+	acpi_status rv = AE_OK;
 
 	/* In most of the case, we know how to set the display, but sometime
 	   we can't read it */
 	if (display_get_handle) {
-		if (!read_acpi_int(display_get_handle, NULL, &value, NULL))
+		rv = acpi_evaluate_integer(display_get_handle, NULL,
+					   NULL, &value);
+		if (ACPI_FAILURE(rv))
 			printk(ASUS_WARNING "Error reading display status\n");
 	}
 
@@ -771,7 +767,7 @@ static int asus_hotk_get_info(void)
 {
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 	union acpi_object *model = NULL;
-	int bsts_result, hwrs_result;
+	ulong bsts_result, hwrs_result;
 	char *string = NULL;
 	acpi_status status;
 
@@ -794,11 +790,13 @@ static int asus_hotk_get_info(void)
 	}
 
 	/* This needs to be called for some laptops to init properly */
-	if (!read_acpi_int(hotk->handle, "BSTS", &bsts_result, NULL))
+	status =
+	    acpi_evaluate_integer(hotk->handle, "BSTS", NULL, &bsts_result);
+	if (ACPI_FAILURE(status))
 		printk(ASUS_WARNING "Error calling BSTS\n");
 	else if (bsts_result)
 		printk(ASUS_NOTICE "BSTS called, 0x%02x returned\n",
-		       bsts_result);
+		       (uint) bsts_result);
 
 	/*
 	 * Try to match the object returned by INIT to the specific model.
@@ -840,7 +838,9 @@ static int asus_hotk_get_info(void)
 	 * The significance of others is yet to be found.
 	 * If we don't find the method, we assume the device are present.
 	 */
-	if (!read_acpi_int(hotk->handle, "HRWS", &hwrs_result, NULL))
+	status =
+	    acpi_evaluate_integer(hotk->handle, "HRWS", NULL, &hwrs_result);
+	if (ACPI_FAILURE(status))
 		hwrs_result = WL_HWRS | BT_HWRS;
 
 	if (hwrs_result & WL_HWRS)
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 014/105] asus-laptop: clean write_status
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Corentin Chary, Len Brown

From: Corentin Chary <corentincj@iksaif.net>

Clean the write_status function, and implement special case with
a switch inside write_status. It also make sure bt and wl status
are right when booting with the hardware switch off.

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/asus-laptop.c |   48 ++++++++++++++++++++++++++-----------------
 1 files changed, 29 insertions(+), 19 deletions(-)

diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c
index dcab778..3ba5798 100644
--- a/drivers/misc/asus-laptop.c
+++ b/drivers/misc/asus-laptop.c
@@ -272,19 +272,25 @@ static int read_status(int mask)
 	return (hotk->status & mask) ? 1 : 0;
 }
 
-static void write_status(acpi_handle handle, int out, int mask, int invert)
+static void write_status(acpi_handle handle, int out, int mask)
 {
 	hotk->status = (out) ? (hotk->status | mask) : (hotk->status & ~mask);
 
-	if (invert)		/* invert target value */
+	switch (mask) {
+	case MLED_ON:
 		out = !out & 0x1;
+		break;
+	default:
+		out &= 0x1;
+		break;
+	}
 
 	if (handle && !write_acpi_int(handle, NULL, out, NULL))
-		printk(ASUS_WARNING " write failed\n");
+		printk(ASUS_WARNING " write failed %x\n", mask);
 }
 
 /* /sys/class/led handlers */
-#define ASUS_LED_HANDLER(object, mask, invert)				\
+#define ASUS_LED_HANDLER(object, mask)					\
 	static void object##_led_set(struct led_classdev *led_cdev,	\
 				     enum led_brightness value)		\
 	{								\
@@ -294,13 +300,13 @@ static void write_status(acpi_handle handle, int out, int mask, int invert)
 	static void object##_led_update(struct work_struct *ignored)	\
 	{								\
 		int value = object##_led_wk;				\
-		write_status(object##_set_handle, value, (mask), (invert)); \
+		write_status(object##_set_handle, value, (mask));	\
 	}
 
-ASUS_LED_HANDLER(mled, MLED_ON, 1);
-ASUS_LED_HANDLER(pled, PLED_ON, 0);
-ASUS_LED_HANDLER(rled, RLED_ON, 0);
-ASUS_LED_HANDLER(tled, TLED_ON, 0);
+ASUS_LED_HANDLER(mled, MLED_ON);
+ASUS_LED_HANDLER(pled, PLED_ON);
+ASUS_LED_HANDLER(rled, RLED_ON);
+ASUS_LED_HANDLER(tled, TLED_ON);
 
 static int get_lcd_state(void)
 {
@@ -325,7 +331,7 @@ static int set_lcd_state(int value)
 			printk(ASUS_WARNING "Error switching LCD\n");
 	}
 
-	write_status(NULL, lcd, LCD_ON, 0);
+	write_status(NULL, lcd, LCD_ON);
 	return 0;
 }
 
@@ -458,7 +464,7 @@ static int parse_arg(const char *buf, unsigned long count, int *val)
 }
 
 static ssize_t store_status(const char *buf, size_t count,
-			    acpi_handle handle, int mask, int invert)
+			    acpi_handle handle, int mask)
 {
 	int rv, value;
 	int out = 0;
@@ -467,7 +473,7 @@ static ssize_t store_status(const char *buf, size_t count,
 	if (rv > 0)
 		out = value ? 1 : 0;
 
-	write_status(handle, out, mask, invert);
+	write_status(handle, out, mask);
 
 	return rv;
 }
@@ -508,7 +514,7 @@ static ssize_t show_wlan(struct device *dev,
 static ssize_t store_wlan(struct device *dev, struct device_attribute *attr,
 			  const char *buf, size_t count)
 {
-	return store_status(buf, count, wl_switch_handle, WL_ON, 0);
+	return store_status(buf, count, wl_switch_handle, WL_ON);
 }
 
 /*
@@ -524,7 +530,7 @@ static ssize_t store_bluetooth(struct device *dev,
 			       struct device_attribute *attr, const char *buf,
 			       size_t count)
 {
-	return store_status(buf, count, bt_switch_handle, BT_ON, 0);
+	return store_status(buf, count, bt_switch_handle, BT_ON);
 }
 
 /*
@@ -652,10 +658,10 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
 	 * switched
 	 */
 	if (event == ATKD_LCD_ON) {
-		write_status(NULL, 1, LCD_ON, 0);
+		write_status(NULL, 1, LCD_ON);
 		lcd_blank(FB_BLANK_UNBLANK);
 	} else if (event == ATKD_LCD_OFF) {
-		write_status(NULL, 0, LCD_ON, 0);
+		write_status(NULL, 0, LCD_ON);
 		lcd_blank(FB_BLANK_POWERDOWN);
 	}
 
@@ -928,11 +934,15 @@ static int asus_hotk_add(struct acpi_device *device)
 	asus_hotk_found = 1;
 
 	/* WLED and BLED are on by default */
-	write_status(bt_switch_handle, 1, BT_ON, 0);
-	write_status(wl_switch_handle, 1, WL_ON, 0);
+	write_status(bt_switch_handle, 1, BT_ON);
+	write_status(wl_switch_handle, 1, WL_ON);
+
+	/* If the h/w switch is off, we need to check the real status */
+	write_status(NULL, read_status(BT_ON), BT_ON);
+	write_status(NULL, read_status(WL_ON), WL_ON);
 
 	/* LCD Backlight is on by default */
-	write_status(NULL, 1, LCD_ON, 0);
+	write_status(NULL, 1, LCD_ON);
 
 	/* LED display is off by default */
 	hotk->ledd_status = 0xFFF;
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 015/105] asus-laptop: add GLED
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Corentin Chary, Len Brown

From: Corentin Chary <corentincj@iksaif.net>

Add support for "gaming" led.

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/asus-laptop.c |   15 ++++++++++++++-
 1 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c
index 3ba5798..475709b 100644
--- a/drivers/misc/asus-laptop.c
+++ b/drivers/misc/asus-laptop.c
@@ -81,7 +81,8 @@
 #define TLED_ON     0x08	//touchpad LED
 #define RLED_ON     0x10	//Record LED
 #define PLED_ON     0x20	//Phone LED
-#define LCD_ON      0x40	//LCD backlight
+#define GLED_ON     0x40	//Gaming LED
+#define LCD_ON      0x80	//LCD backlight
 
 #define ASUS_LOG    ASUS_HOTK_FILE ": "
 #define ASUS_ERR    KERN_ERR    ASUS_LOG
@@ -103,6 +104,7 @@ ASUS_HANDLE(mled_set, ASUS_HOTK_PREFIX "MLED");
 ASUS_HANDLE(tled_set, ASUS_HOTK_PREFIX "TLED");
 ASUS_HANDLE(rled_set, ASUS_HOTK_PREFIX "RLED");	/* W1JC */
 ASUS_HANDLE(pled_set, ASUS_HOTK_PREFIX "PLED");	/* A7J */
+ASUS_HANDLE(gled_set, ASUS_HOTK_PREFIX "GLED");	/* G1, G2 (probably) */
 
 /* LEDD */
 ASUS_HANDLE(ledd_set, ASUS_HOTK_PREFIX "SLCM");
@@ -221,6 +223,7 @@ ASUS_LED(mled, "mail");
 ASUS_LED(tled, "touchpad");
 ASUS_LED(rled, "record");
 ASUS_LED(pled, "phone");
+ASUS_LED(gled, "gaming");
 
 /*
  * This function evaluates an ACPI method, given an int as parameter, the
@@ -280,6 +283,9 @@ static void write_status(acpi_handle handle, int out, int mask)
 	case MLED_ON:
 		out = !out & 0x1;
 		break;
+	case GLED_ON:
+		out = (out & 0x1) + 1;
+		break;
 	default:
 		out &= 0x1;
 		break;
@@ -307,6 +313,7 @@ ASUS_LED_HANDLER(mled, MLED_ON);
 ASUS_LED_HANDLER(pled, PLED_ON);
 ASUS_LED_HANDLER(rled, RLED_ON);
 ASUS_LED_HANDLER(tled, TLED_ON);
+ASUS_LED_HANDLER(gled, GLED_ON);
 
 static int get_lcd_state(void)
 {
@@ -835,6 +842,7 @@ static int asus_hotk_get_info(void)
 	ASUS_HANDLE_INIT(tled_set);
 	ASUS_HANDLE_INIT(rled_set);
 	ASUS_HANDLE_INIT(pled_set);
+	ASUS_HANDLE_INIT(gled_set);
 
 	ASUS_HANDLE_INIT(ledd_set);
 
@@ -1001,6 +1009,7 @@ static void asus_led_exit(void)
 	ASUS_LED_UNREGISTER(tled);
 	ASUS_LED_UNREGISTER(pled);
 	ASUS_LED_UNREGISTER(rled);
+	ASUS_LED_UNREGISTER(gled);
 
 	destroy_workqueue(led_workqueue);
 }
@@ -1072,6 +1081,10 @@ static int asus_led_init(struct device *dev)
 	if (rv)
 		return rv;
 
+	rv = ASUS_LED_REGISTER(gled, dev);
+	if (rv)
+		return rv;
+
 	led_workqueue = create_singlethread_workqueue("led_workqueue");
 	if (!led_workqueue)
 		return -ENOMEM;
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 016/105] asus-laptop: add wapf param
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Corentin Chary, Len Brown

From: Corentin Chary <corentincj@iksaif.net>

Add the "wapf" param. This param allows to define the behavior
of  the Fn F2 key (wlan switch).

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/asus-laptop.c |   16 ++++++++++++++++
 1 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c
index 475709b..d75e447 100644
--- a/drivers/misc/asus-laptop.c
+++ b/drivers/misc/asus-laptop.c
@@ -95,6 +95,19 @@ MODULE_AUTHOR("Julien Lerouge, Karol Kozimor, Corentin Chary");
 MODULE_DESCRIPTION(ASUS_HOTK_NAME);
 MODULE_LICENSE("GPL");
 
+/* WAPF defines the behavior of the Fn+Fx wlan key
+ * The significance of values is yet to be found, but
+ * most of the time:
+ * 0x0 will do nothing
+ * 0x1 will allow to control the device with Fn+Fx key.
+ * 0x4 will send an ACPI event (0x88) while pressing the Fn+Fx key
+ * 0x5 like 0x1 or 0x4
+ * So, if something doesn't work as you want, just try other values =)
+ */
+static uint wapf = 1;
+module_param(wapf, uint, 0644);
+MODULE_PARM_DESC(wapf, "WAPF value");
+
 #define ASUS_HANDLE(object, paths...)					\
 	static acpi_handle  object##_handle = NULL;			\
 	static char *object##_paths[] = { paths }
@@ -811,6 +824,9 @@ static int asus_hotk_get_info(void)
 		printk(ASUS_NOTICE "BSTS called, 0x%02x returned\n",
 		       (uint) bsts_result);
 
+	/* This too ... */
+	write_acpi_int(hotk->handle, "CWAP", wapf, NULL);
+
 	/*
 	 * Try to match the object returned by INIT to the specific model.
 	 * Handle every possible object (or the lack of thereof) the DSDT
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 017/105] asus-laptop: version bump
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Corentin Chary, Len Brown

From: Corentin Chary <corentincj@iksaif.net>

Version and copyright bump.

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/asus-laptop.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c
index d75e447..65c32a9 100644
--- a/drivers/misc/asus-laptop.c
+++ b/drivers/misc/asus-laptop.c
@@ -3,7 +3,7 @@
  *
  *
  *  Copyright (C) 2002-2005 Julien Lerouge, 2003-2006 Karol Kozimor
- *  Copyright (C) 2006 Corentin Chary
+ *  Copyright (C) 2006-2007 Corentin Chary
  *
  *  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
@@ -48,7 +48,7 @@
 #include <acpi/acpi_bus.h>
 #include <asm/uaccess.h>
 
-#define ASUS_LAPTOP_VERSION "0.40"
+#define ASUS_LAPTOP_VERSION "0.41"
 
 #define ASUS_HOTK_NAME          "Asus Laptop Support"
 #define ASUS_HOTK_CLASS         "hotkey"
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 018/105] ACPI: sbs: use EC rather than I2C
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Vladimir Lebedev, Len Brown

From: Vladimir Lebedev <vladimir.p.lebedev@intel.com>

SBS is based on EC function(ec_read/ec_write).
Not needed using of I2C structures/functions ... is removed.
SBS does not depend on I2C now.

Signed-off-by: Vladimir Lebedev <vladimir.p.lebedev@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/sbs.c |  565 ++++++++++++++++++++++++++--------------------------
 1 files changed, 287 insertions(+), 278 deletions(-)

diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 59640d9..eab5c68 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -30,30 +30,9 @@
 #include <linux/seq_file.h>
 #include <asm/uaccess.h>
 #include <linux/acpi.h>
-#include <linux/i2c.h>
+#include <linux/timer.h>
 #include <linux/delay.h>
 
-#include "i2c_ec.h"
-
-#define	DEF_CAPACITY_UNIT	3
-#define	MAH_CAPACITY_UNIT	1
-#define	MWH_CAPACITY_UNIT	2
-#define	CAPACITY_UNIT		DEF_CAPACITY_UNIT
-
-#define	REQUEST_UPDATE_MODE	1
-#define	QUEUE_UPDATE_MODE	2
-
-#define	DATA_TYPE_COMMON	0
-#define	DATA_TYPE_INFO		1
-#define	DATA_TYPE_STATE		2
-#define	DATA_TYPE_ALARM		3
-#define	DATA_TYPE_AC_STATE	4
-
-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 ACPI_SBS_COMPONENT		0x00080000
 #define ACPI_SBS_CLASS			"sbs"
 #define ACPI_AC_CLASS			"ac_adapter"
@@ -74,15 +53,62 @@ extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
 
 #define _COMPONENT			ACPI_SBS_COMPONENT
 
-#define	MAX_SBS_BAT			4
-#define	MAX_SMBUS_ERR			1
-
 ACPI_MODULE_NAME("sbs");
 
 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
+#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
+
+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 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
+
 static struct semaphore sbs_sem;
 
 #define	UPDATE_MODE		QUEUE_UPDATE_MODE
@@ -105,7 +131,6 @@ module_param(update_time2, int, 0);
 
 static int acpi_sbs_add(struct acpi_device *device);
 static int acpi_sbs_remove(struct acpi_device *device, int type);
-static void acpi_battery_smbus_err_handler(struct acpi_ec_smbus *smbus);
 static void acpi_sbs_update_queue(void *data);
 
 static struct acpi_driver acpi_sbs_driver = {
@@ -126,9 +151,9 @@ struct acpi_battery_info {
 	int vscale;
 	int ipscale;
 	s16 serial_number;
-	char manufacturer_name[I2C_SMBUS_BLOCK_MAX + 3];
-	char device_name[I2C_SMBUS_BLOCK_MAX + 3];
-	char device_chemistry[I2C_SMBUS_BLOCK_MAX + 3];
+	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 {
@@ -158,8 +183,8 @@ struct acpi_battery {
 
 struct acpi_sbs {
 	acpi_handle handle;
+	int base;
 	struct acpi_device *device;
-	struct acpi_ec_smbus *smbus;
 	int sbsm_present;
 	int sbsm_batteries_supported;
 	int ac_present;
@@ -172,6 +197,14 @@ struct acpi_sbs {
 	struct timer_list update_timer;
 };
 
+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);
 static void acpi_update_delay(struct acpi_sbs *sbs);
 static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type);
 
@@ -179,155 +212,172 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type);
                                SMBus Communication
    -------------------------------------------------------------------------- */
 
-static void acpi_battery_smbus_err_handler(struct acpi_ec_smbus *smbus)
+static int acpi_ec_sbs_read(struct acpi_sbs *sbs, u8 address, u8 * data)
 {
-	union i2c_smbus_data data;
-	int result = 0;
-	char *err_str;
-	int err_number;
+	u8 val;
+	int err;
 
-	data.word = 0;
+	err = ec_read(sbs->base + address, &val);
+	if (!err) {
+		*data = val;
+	}
+	xmsleep(ACPI_EC_SMB_TRANSACTION_SLEEP);
+	return (err);
+}
 
-	result = smbus->adapter.algo->
-	    smbus_xfer(&smbus->adapter,
-		       ACPI_SB_SMBUS_ADDR,
-		       0, I2C_SMBUS_READ, 0x16, I2C_SMBUS_BLOCK_DATA, &data);
+static int acpi_ec_sbs_write(struct acpi_sbs *sbs, u8 address, u8 data)
+{
+	int err;
 
-	err_number = (data.word & 0x000f);
+	err = ec_write(sbs->base + address, data);
+	return (err);
+}
 
-	switch (data.word & 0x000f) {
-	case 0x0000:
-		err_str = "unexpected bus error";
-		break;
-	case 0x0001:
-		err_str = "busy";
-		break;
-	case 0x0002:
-		err_str = "reserved command";
-		break;
-	case 0x0003:
-		err_str = "unsupported command";
-		break;
-	case 0x0004:
-		err_str = "access denied";
+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 0x0005:
-		err_str = "overflow/underflow";
+	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;
-	case 0x0006:
-		err_str = "bad size";
+	default:
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"unsupported transaction %d\n", 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\n", 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 0x0007:
-		err_str = "unknown error";
+
+	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:
-		err_str = "unrecognized error";
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"unsupported transaction %d\n", size));
+		return (-1);
 	}
-	ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-			  "%s: ret %i, err %i\n", err_str, result, err_number));
+
+	return (0);
 }
 
 static int
-acpi_sbs_smbus_read_word(struct acpi_ec_smbus *smbus, int addr, int func,
-			 u16 * word,
-			 void (*err_handler) (struct acpi_ec_smbus * smbus))
+acpi_sbs_read_word(struct acpi_sbs *sbs, int addr, int func, u16 * word)
 {
-	union i2c_smbus_data data;
+	union sbs_rw_data data;
 	int result = 0;
-	int i;
 
-	if (err_handler == NULL) {
-		err_handler = acpi_battery_smbus_err_handler;
-	}
-
-	for (i = 0; i < MAX_SMBUS_ERR; i++) {
-		result =
-		    smbus->adapter.algo->smbus_xfer(&smbus->adapter, addr, 0,
-						    I2C_SMBUS_READ, func,
-						    I2C_SMBUS_WORD_DATA, &data);
-		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "try %i: smbus->adapter.algo->smbus_xfer() failed\n",
-					  i));
-			if (err_handler) {
-				err_handler(smbus);
-			}
-		} else {
-			*word = data.word;
-			break;
-		}
+	result = acpi_ec_sbs_access(sbs, addr,
+				    ACPI_SBS_SMBUS_READ, func,
+				    ACPI_SBS_WORD_DATA, &data);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_ec_sbs_access() failed\n"));
+	} else {
+		*word = data.word;
 	}
 
 	return result;
 }
 
 static int
-acpi_sbs_smbus_read_str(struct acpi_ec_smbus *smbus, int addr, int func,
-			char *str,
-			void (*err_handler) (struct acpi_ec_smbus * smbus))
+acpi_sbs_read_str(struct acpi_sbs *sbs, int addr, int func, char *str)
 {
-	union i2c_smbus_data data;
+	union sbs_rw_data data;
 	int result = 0;
-	int i;
-
-	if (err_handler == NULL) {
-		err_handler = acpi_battery_smbus_err_handler;
-	}
 
-	for (i = 0; i < MAX_SMBUS_ERR; i++) {
-		result =
-		    smbus->adapter.algo->smbus_xfer(&smbus->adapter, addr, 0,
-						    I2C_SMBUS_READ, func,
-						    I2C_SMBUS_BLOCK_DATA,
-						    &data);
-		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "try %i: smbus->adapter.algo->smbus_xfer() failed\n",
-					  i));
-			if (err_handler) {
-				err_handler(smbus);
-			}
-		} else {
-			strncpy(str, (const char *)data.block + 1,
-				data.block[0]);
-			str[data.block[0]] = 0;
-			break;
-		}
+	result = acpi_ec_sbs_access(sbs, addr,
+				    ACPI_SBS_SMBUS_READ, func,
+				    ACPI_SBS_BLOCK_DATA, &data);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_ec_sbs_access() failed\n"));
+	} else {
+		strncpy(str, (const char *)data.block + 1, data.block[0]);
+		str[data.block[0]] = 0;
 	}
 
 	return result;
 }
 
 static int
-acpi_sbs_smbus_write_word(struct acpi_ec_smbus *smbus, int addr, int func,
-			  int word,
-			  void (*err_handler) (struct acpi_ec_smbus * smbus))
+acpi_sbs_write_word(struct acpi_sbs *sbs, int addr, int func, int word)
 {
-	union i2c_smbus_data data;
+	union sbs_rw_data data;
 	int result = 0;
-	int i;
-
-	if (err_handler == NULL) {
-		err_handler = acpi_battery_smbus_err_handler;
-	}
 
 	data.word = word;
 
-	for (i = 0; i < MAX_SMBUS_ERR; i++) {
-		result =
-		    smbus->adapter.algo->smbus_xfer(&smbus->adapter, addr, 0,
-						    I2C_SMBUS_WRITE, func,
-						    I2C_SMBUS_WORD_DATA, &data);
-		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "try %i: smbus->adapter.algo"
-					  "->smbus_xfer() failed\n", i));
-			if (err_handler) {
-				err_handler(smbus);
-			}
-		} else {
-			break;
-		}
+	result = acpi_ec_sbs_access(sbs, addr,
+				    ACPI_SBS_SMBUS_WRITE, func,
+				    ACPI_SBS_WORD_DATA, &data);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "acpi_ec_sbs_access() failed\n"));
 	}
 
 	return result;
@@ -366,12 +416,11 @@ static int acpi_battery_get_present(struct acpi_battery *battery)
 	int result = 0;
 	int is_present = 0;
 
-	result = acpi_sbs_smbus_read_word(battery->sbs->smbus,
-					  ACPI_SBSM_SMBUS_ADDR, 0x01,
-					  &state, NULL);
+	result = acpi_sbs_read_word(battery->sbs,
+				    ACPI_SBSM_SMBUS_ADDR, 0x01, &state);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed"));
+				  "acpi_sbs_read_word() failed"));
 	}
 	if (!result) {
 		is_present = (state & 0x000f) & (1 << battery->id);
@@ -393,7 +442,7 @@ static int acpi_ac_is_present(struct acpi_sbs *sbs)
 
 static int acpi_battery_select(struct acpi_battery *battery)
 {
-	struct acpi_ec_smbus *smbus = battery->sbs->smbus;
+	struct acpi_sbs *sbs = battery->sbs;
 	int result = 0;
 	s16 state;
 	int foo;
@@ -405,21 +454,19 @@ static int acpi_battery_select(struct acpi_battery *battery)
 		 * it causes charging to halt on SBSELs */
 
 		result =
-		    acpi_sbs_smbus_read_word(smbus, ACPI_SBSM_SMBUS_ADDR, 0x01,
-					     &state, NULL);
+		    acpi_sbs_read_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x01, &state);
 		if (result) {
 			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_smbus_read_word() failed\n"));
+					  "acpi_sbs_read_word() failed\n"));
 			goto end;
 		}
 
 		foo = (state & 0x0fff) | (1 << (battery->id + 12));
 		result =
-		    acpi_sbs_smbus_write_word(smbus, ACPI_SBSM_SMBUS_ADDR, 0x01,
-					      foo, NULL);
+		    acpi_sbs_write_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x01, foo);
 		if (result) {
 			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_smbus_write_word() failed\n"));
+					  "acpi_sbs_write_word() failed\n"));
 			goto end;
 		}
 	}
@@ -430,15 +477,14 @@ static int acpi_battery_select(struct acpi_battery *battery)
 
 static int acpi_sbsm_get_info(struct acpi_sbs *sbs)
 {
-	struct acpi_ec_smbus *smbus = sbs->smbus;
 	int result = 0;
 	s16 battery_system_info;
 
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SBSM_SMBUS_ADDR, 0x04,
-					  &battery_system_info, NULL);
+	result = acpi_sbs_read_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x04,
+				    &battery_system_info);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+				  "acpi_sbs_read_word() failed\n"));
 		goto end;
 	}
 
@@ -451,53 +497,48 @@ static int acpi_sbsm_get_info(struct acpi_sbs *sbs)
 
 static int acpi_battery_get_info(struct acpi_battery *battery)
 {
-	struct acpi_ec_smbus *smbus = battery->sbs->smbus;
+	struct acpi_sbs *sbs = battery->sbs;
 	int result = 0;
 	s16 battery_mode;
 	s16 specification_info;
 
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x03,
-					  &battery_mode,
-					  &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x03,
+				    &battery_mode);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+				  "acpi_sbs_read_word() failed\n"));
 		goto end;
 	}
 	battery->info.capacity_mode = (battery_mode & 0x8000) >> 15;
 
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x10,
-					  &battery->info.full_charge_capacity,
-					  &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x10,
+				    &battery->info.full_charge_capacity);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+				  "acpi_sbs_read_word() failed\n"));
 		goto end;
 	}
 
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x18,
-					  &battery->info.design_capacity,
-					  &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x18,
+				    &battery->info.design_capacity);
 
 	if (result) {
 		goto end;
 	}
 
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x19,
-					  &battery->info.design_voltage,
-					  &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x19,
+				    &battery->info.design_voltage);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+				  "acpi_sbs_read_word() failed\n"));
 		goto end;
 	}
 
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x1a,
-					  &specification_info,
-					  &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1a,
+				    &specification_info);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+				  "acpi_sbs_read_word() failed\n"));
 		goto end;
 	}
 
@@ -529,37 +570,33 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 		battery->info.ipscale = 1;
 	}
 
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x1c,
-					  &battery->info.serial_number,
-					  &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1c,
+				    &battery->info.serial_number);
 	if (result) {
 		goto end;
 	}
 
-	result = acpi_sbs_smbus_read_str(smbus, ACPI_SB_SMBUS_ADDR, 0x20,
-					 battery->info.manufacturer_name,
-					 &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x20,
+				   battery->info.manufacturer_name);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_str() failed\n"));
+				  "acpi_sbs_read_str() failed\n"));
 		goto end;
 	}
 
-	result = acpi_sbs_smbus_read_str(smbus, ACPI_SB_SMBUS_ADDR, 0x21,
-					 battery->info.device_name,
-					 &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x21,
+				   battery->info.device_name);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_str() failed\n"));
+				  "acpi_sbs_read_str() failed\n"));
 		goto end;
 	}
 
-	result = acpi_sbs_smbus_read_str(smbus, ACPI_SB_SMBUS_ADDR, 0x22,
-					 battery->info.device_chemistry,
-					 &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x22,
+				   battery->info.device_chemistry);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_str() failed\n"));
+				  "acpi_sbs_read_str() failed\n"));
 		goto end;
 	}
 
@@ -579,66 +616,60 @@ static void acpi_update_delay(struct acpi_sbs *sbs)
 
 static int acpi_battery_get_state(struct acpi_battery *battery)
 {
-	struct acpi_ec_smbus *smbus = battery->sbs->smbus;
+	struct acpi_sbs *sbs = battery->sbs;
 	int result = 0;
 
 	acpi_update_delay(battery->sbs);
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x09,
-					  &battery->state.voltage,
-					  &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x09,
+				    &battery->state.voltage);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+				  "acpi_sbs_read_word() failed\n"));
 		goto end;
 	}
 
 	acpi_update_delay(battery->sbs);
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x0a,
-					  &battery->state.amperage,
-					  &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0a,
+				    &battery->state.amperage);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+				  "acpi_sbs_read_word() failed\n"));
 		goto end;
 	}
 
 	acpi_update_delay(battery->sbs);
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x0f,
-					  &battery->state.remaining_capacity,
-					  &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0f,
+				    &battery->state.remaining_capacity);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+				  "acpi_sbs_read_word() failed\n"));
 		goto end;
 	}
 
 	acpi_update_delay(battery->sbs);
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x12,
-					  &battery->state.average_time_to_empty,
-					  &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x12,
+				    &battery->state.average_time_to_empty);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+				  "acpi_sbs_read_word() failed\n"));
 		goto end;
 	}
 
 	acpi_update_delay(battery->sbs);
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x13,
-					  &battery->state.average_time_to_full,
-					  &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x13,
+				    &battery->state.average_time_to_full);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+				  "acpi_sbs_read_word() failed\n"));
 		goto end;
 	}
 
 	acpi_update_delay(battery->sbs);
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x16,
-					  &battery->state.battery_status,
-					  &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x16,
+				    &battery->state.battery_status);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+				  "acpi_sbs_read_word() failed\n"));
 		goto end;
 	}
 
@@ -650,15 +681,14 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 
 static int acpi_battery_get_alarm(struct acpi_battery *battery)
 {
-	struct acpi_ec_smbus *smbus = battery->sbs->smbus;
+	struct acpi_sbs *sbs = battery->sbs;
 	int result = 0;
 
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x01,
-					  &battery->alarm.remaining_capacity,
-					  &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01,
+				    &battery->alarm.remaining_capacity);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+				  "acpi_sbs_read_word() failed\n"));
 		goto end;
 	}
 
@@ -672,7 +702,7 @@ 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_ec_smbus *smbus = battery->sbs->smbus;
+	struct acpi_sbs *sbs = battery->sbs;
 	int result = 0;
 	s16 battery_mode;
 	int foo;
@@ -688,33 +718,29 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
 
 	if (alarm > 0) {
 		result =
-		    acpi_sbs_smbus_read_word(smbus, ACPI_SB_SMBUS_ADDR, 0x03,
-					     &battery_mode,
-					     &acpi_battery_smbus_err_handler);
+		    acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x03,
+				       &battery_mode);
 		if (result) {
 			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_smbus_read_word() failed\n"));
+					  "acpi_sbs_read_word() failed\n"));
 			goto end;
 		}
 
 		result =
-		    acpi_sbs_smbus_write_word(smbus, ACPI_SB_SMBUS_ADDR, 0x01,
-					      battery_mode & 0xbfff,
-					      &acpi_battery_smbus_err_handler);
+		    acpi_sbs_write_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01,
+					battery_mode & 0xbfff);
 		if (result) {
 			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_smbus_write_word() failed\n"));
+					  "acpi_sbs_write_word() failed\n"));
 			goto end;
 		}
 	}
 
 	foo = alarm / (battery->info.capacity_mode ? 10 : 1);
-	result = acpi_sbs_smbus_write_word(smbus, ACPI_SB_SMBUS_ADDR, 0x01,
-					   foo,
-					   &acpi_battery_smbus_err_handler);
+	result = acpi_sbs_write_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01, foo);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_write_word() failed\n"));
+				  "acpi_sbs_write_word() failed\n"));
 		goto end;
 	}
 
@@ -732,12 +758,11 @@ static int acpi_battery_set_mode(struct acpi_battery *battery)
 		goto end;
 	}
 
-	result = acpi_sbs_smbus_read_word(battery->sbs->smbus,
-					  ACPI_SB_SMBUS_ADDR, 0x03,
-					  &battery_mode, NULL);
+	result = acpi_sbs_read_word(battery->sbs,
+				    ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+				  "acpi_sbs_read_word() failed\n"));
 		goto end;
 	}
 
@@ -746,21 +771,19 @@ static int acpi_battery_set_mode(struct acpi_battery *battery)
 	} else {
 		battery_mode |= 0x8000;
 	}
-	result = acpi_sbs_smbus_write_word(battery->sbs->smbus,
-					   ACPI_SB_SMBUS_ADDR, 0x03,
-					   battery_mode, NULL);
+	result = acpi_sbs_write_word(battery->sbs,
+				     ACPI_SB_SMBUS_ADDR, 0x03, battery_mode);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_write_word() failed\n"));
+				  "acpi_sbs_write_word() failed\n"));
 		goto end;
 	}
 
-	result = acpi_sbs_smbus_read_word(battery->sbs->smbus,
-					  ACPI_SB_SMBUS_ADDR, 0x03,
-					  &battery_mode, NULL);
+	result = acpi_sbs_read_word(battery->sbs,
+				    ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+				  "acpi_sbs_read_word() failed\n"));
 		goto end;
 	}
 
@@ -813,16 +836,15 @@ static int acpi_battery_init(struct acpi_battery *battery)
 
 static int acpi_ac_get_present(struct acpi_sbs *sbs)
 {
-	struct acpi_ec_smbus *smbus = sbs->smbus;
 	int result = 0;
 	s16 charger_status;
 
-	result = acpi_sbs_smbus_read_word(smbus, ACPI_SBC_SMBUS_ADDR, 0x13,
-					  &charger_status, NULL);
+	result = acpi_sbs_read_word(sbs, ACPI_SBC_SMBUS_ADDR, 0x13,
+				    &charger_status);
 
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_smbus_read_word() failed\n"));
+				  "acpi_sbs_read_word() failed\n"));
 		goto end;
 	}
 
@@ -1567,38 +1589,27 @@ static void acpi_sbs_update_queue(void *data)
 static int acpi_sbs_add(struct acpi_device *device)
 {
 	struct acpi_sbs *sbs = NULL;
-	struct acpi_ec_hc *ec_hc = NULL;
-	int result, remove_result = 0;
+	int result;
 	unsigned long sbs_obj;
-	int id, cnt;
+	int id;
 	acpi_status status = AE_OK;
+	unsigned long val;
+
+	status =
+	    acpi_evaluate_integer(device->parent->handle, "_EC", NULL, &val);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error obtaining _EC\n"));
+		return -EIO;
+	}
 
 	sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL);
 	if (!sbs) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "kmalloc() failed\n"));
 		return -ENOMEM;
 	}
-
-	cnt = 0;
-	while (cnt < 10) {
-		cnt++;
-		ec_hc = acpi_get_ec_hc(device);
-		if (ec_hc) {
-			break;
-		}
-		msleep(1000);
-	}
-
-	if (!ec_hc) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_get_ec_hc() failed: "
-				  "NO driver found for EC HC SMBus\n"));
-		result = -ENODEV;
-		goto end;
-	}
+	sbs->base = (val & 0xff00ull) >> 8;
 
 	sbs->device = device;
-	sbs->smbus = ec_hc->smbus;
 
 	strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_SBS_CLASS);
@@ -1669,11 +1680,7 @@ static int acpi_sbs_add(struct acpi_device *device)
 
       end:
 	if (result) {
-		remove_result = acpi_sbs_remove(device, 0);
-		if (remove_result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_remove() failed\n"));
-		}
+		acpi_sbs_remove(device, 0);
 	}
 
 	return result;
@@ -1707,6 +1714,8 @@ int acpi_sbs_remove(struct acpi_device *device, int type)
 
 	acpi_ac_remove(sbs);
 
+	acpi_driver_data(device) = NULL;
+
 	kfree(sbs);
 
 	return 0;
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 019/105] ACPI: sbs: remove I2C Kconfig dependency
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Vladimir Lebedev, Len Brown

From: Vladimir Lebedev <vladimir.p.lebedev@intel.com>

SBS does not depend on I2C.

Signed-off-by: Vladimir Lebedev <vladimir.p.lebedev@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/Kconfig |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index e2ce4a9..d9d9721 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -388,11 +388,10 @@ config ACPI_HOTPLUG_MEMORY
 
 config ACPI_SBS
 	tristate "Smart Battery System (EXPERIMENTAL)"
-	depends on X86 && I2C
+	depends on X86
 	depends on EXPERIMENTAL
 	help
 	  This driver adds support for the Smart Battery System.
-	  Depends on I2C (Device Drivers ---> I2C support)
 	  A "Smart Battery" is quite old and quite rare compared
 	  to today's ACPI "Control Method" battery.
 
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 020/105] ACPI: sbs: remove I2C Makefile hooks
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Vladimir Lebedev, Len Brown

From: Vladimir Lebedev <vladimir.p.lebedev@intel.com>

SBS does not depend on I2C.
i2c_ec.h and i2c_ec.c are not needed

Signed-off-by: Vladimir Lebedev <vladimir.p.lebedev@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/Makefile |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 5956e9f..55bbc40 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -59,4 +59,4 @@ obj-$(CONFIG_ACPI_IBM)		+= ibm_acpi.o
 obj-$(CONFIG_ACPI_TOSHIBA)	+= toshiba_acpi.o
 obj-$(CONFIG_ACPI_HOTPLUG_MEMORY)	+= acpi_memhotplug.o
 obj-y				+= cm_sbs.o
-obj-$(CONFIG_ACPI_SBS)		+= i2c_ec.o sbs.o
+obj-$(CONFIG_ACPI_SBS)		+= sbs.o
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 021/105] ACPI: sbs: Debug messages correction/improvement
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Vladimir Lebedev, Len Brown

From: Vladimir Lebedev <vladimir.p.lebedev@intel.com>

Debug messages correction/improvement:
Use ACPI_EXCEPTION instead of ACPI_DEBUG_PRINT.

Signed-off-by: Vladimir Lebedev <vladimir.p.lebedev@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/sbs.c |  299 ++++++++++++++++++++++++++--------------------------
 1 files changed, 149 insertions(+), 150 deletions(-)

diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index eab5c68..3956645 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -271,7 +271,7 @@ acpi_ec_sbs_access(struct acpi_sbs *sbs, u16 addr,
 		break;
 	default:
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"unsupported transaction %d\n", size));
+				"unsupported transaction %d", size));
 		return (-1);
 	}
 
@@ -291,7 +291,7 @@ acpi_ec_sbs_access(struct acpi_sbs *sbs, u16 addr,
 	if ((~temp[0] & ACPI_EC_SMB_STS_DONE)
 	    || (temp[0] & ACPI_EC_SMB_STS_STATUS)) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"transaction %d error\n", size));
+				"transaction %d error", size));
 		return (-1);
 	}
 
@@ -318,7 +318,7 @@ acpi_ec_sbs_access(struct acpi_sbs *sbs, u16 addr,
 		break;
 	default:
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"unsupported transaction %d\n", size));
+				"unsupported transaction %d", size));
 		return (-1);
 	}
 
@@ -335,8 +335,8 @@ acpi_sbs_read_word(struct acpi_sbs *sbs, int addr, int func, u16 * word)
 				    ACPI_SBS_SMBUS_READ, func,
 				    ACPI_SBS_WORD_DATA, &data);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_ec_sbs_access() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_ec_sbs_access() failed"));
 	} else {
 		*word = data.word;
 	}
@@ -354,8 +354,8 @@ acpi_sbs_read_str(struct acpi_sbs *sbs, int addr, int func, char *str)
 				    ACPI_SBS_SMBUS_READ, func,
 				    ACPI_SBS_BLOCK_DATA, &data);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_ec_sbs_access() failed\n"));
+		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;
@@ -376,8 +376,8 @@ acpi_sbs_write_word(struct acpi_sbs *sbs, int addr, int func, int word)
 				    ACPI_SBS_SMBUS_WRITE, func,
 				    ACPI_SBS_WORD_DATA, &data);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_ec_sbs_access() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_ec_sbs_access() failed"));
 	}
 
 	return result;
@@ -419,8 +419,8 @@ static int acpi_battery_get_present(struct acpi_battery *battery)
 	result = acpi_sbs_read_word(battery->sbs,
 				    ACPI_SBSM_SMBUS_ADDR, 0x01, &state);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_read_word() failed"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_read_word() failed"));
 	}
 	if (!result) {
 		is_present = (state & 0x000f) & (1 << battery->id);
@@ -456,8 +456,8 @@ static int acpi_battery_select(struct acpi_battery *battery)
 		result =
 		    acpi_sbs_read_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x01, &state);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_read_word() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbs_read_word() failed"));
 			goto end;
 		}
 
@@ -465,8 +465,8 @@ static int acpi_battery_select(struct acpi_battery *battery)
 		result =
 		    acpi_sbs_write_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x01, foo);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_write_word() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbs_write_word() failed"));
 			goto end;
 		}
 	}
@@ -483,8 +483,8 @@ static int acpi_sbsm_get_info(struct acpi_sbs *sbs)
 	result = acpi_sbs_read_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x04,
 				    &battery_system_info);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_read_word() failed"));
 		goto end;
 	}
 
@@ -505,8 +505,8 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x03,
 				    &battery_mode);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_read_word() failed"));
 		goto end;
 	}
 	battery->info.capacity_mode = (battery_mode & 0x8000) >> 15;
@@ -514,8 +514,8 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x10,
 				    &battery->info.full_charge_capacity);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_read_word() failed"));
 		goto end;
 	}
 
@@ -529,16 +529,16 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x19,
 				    &battery->info.design_voltage);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_read_word() failed"));
 		goto end;
 	}
 
 	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1a,
 				    &specification_info);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_read_word() failed"));
 		goto end;
 	}
 
@@ -579,24 +579,24 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 	result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x20,
 				   battery->info.manufacturer_name);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_read_str() failed\n"));
+		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);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_read_str() failed\n"));
+		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);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_read_str() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_read_str() failed"));
 		goto end;
 	}
 
@@ -623,8 +623,8 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x09,
 				    &battery->state.voltage);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_read_word() failed"));
 		goto end;
 	}
 
@@ -632,8 +632,8 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0a,
 				    &battery->state.amperage);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_read_word() failed"));
 		goto end;
 	}
 
@@ -641,8 +641,8 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0f,
 				    &battery->state.remaining_capacity);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_read_word() failed"));
 		goto end;
 	}
 
@@ -650,8 +650,8 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x12,
 				    &battery->state.average_time_to_empty);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_read_word() failed"));
 		goto end;
 	}
 
@@ -659,8 +659,8 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x13,
 				    &battery->state.average_time_to_full);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_read_word() failed"));
 		goto end;
 	}
 
@@ -668,8 +668,8 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x16,
 				    &battery->state.battery_status);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_read_word() failed"));
 		goto end;
 	}
 
@@ -687,8 +687,8 @@ static int acpi_battery_get_alarm(struct acpi_battery *battery)
 	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01,
 				    &battery->alarm.remaining_capacity);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_read_word() failed"));
 		goto end;
 	}
 
@@ -709,8 +709,8 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
 
 	result = acpi_battery_select(battery);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_battery_select() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_battery_select() failed"));
 		goto end;
 	}
 
@@ -721,8 +721,8 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
 		    acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x03,
 				       &battery_mode);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_read_word() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbs_read_word() failed"));
 			goto end;
 		}
 
@@ -730,8 +730,8 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
 		    acpi_sbs_write_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01,
 					battery_mode & 0xbfff);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_write_word() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbs_write_word() failed"));
 			goto end;
 		}
 	}
@@ -739,8 +739,8 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
 	foo = alarm / (battery->info.capacity_mode ? 10 : 1);
 	result = acpi_sbs_write_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01, foo);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_write_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_write_word() failed"));
 		goto end;
 	}
 
@@ -761,8 +761,8 @@ static int acpi_battery_set_mode(struct acpi_battery *battery)
 	result = acpi_sbs_read_word(battery->sbs,
 				    ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_read_word() failed"));
 		goto end;
 	}
 
@@ -774,16 +774,16 @@ static int acpi_battery_set_mode(struct acpi_battery *battery)
 	result = acpi_sbs_write_word(battery->sbs,
 				     ACPI_SB_SMBUS_ADDR, 0x03, battery_mode);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_write_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_write_word() failed"));
 		goto end;
 	}
 
 	result = acpi_sbs_read_word(battery->sbs,
 				    ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_read_word() failed"));
 		goto end;
 	}
 
@@ -797,36 +797,36 @@ static int acpi_battery_init(struct acpi_battery *battery)
 
 	result = acpi_battery_select(battery);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_battery_init() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_battery_init() failed"));
 		goto end;
 	}
 
 	result = acpi_battery_set_mode(battery);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_battery_set_mode() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_battery_set_mode() failed"));
 		goto end;
 	}
 
 	result = acpi_battery_get_info(battery);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_battery_get_info() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_battery_get_info() failed"));
 		goto end;
 	}
 
 	result = acpi_battery_get_state(battery);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_battery_get_state() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_battery_get_state() failed"));
 		goto end;
 	}
 
 	result = acpi_battery_get_alarm(battery);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_battery_get_alarm() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_battery_get_alarm() failed"));
 		goto end;
 	}
 
@@ -843,8 +843,8 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)
 				    &charger_status);
 
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_read_word() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_read_word() failed"));
 		goto end;
 	}
 
@@ -874,8 +874,8 @@ acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
 	if (!*dir) {
 		*dir = proc_mkdir(dir_name, parent_dir);
 		if (!*dir) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "proc_mkdir() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"proc_mkdir() failed"));
 			return -ENODEV;
 		}
 		(*dir)->owner = THIS_MODULE;
@@ -885,8 +885,8 @@ acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
 	if (info_fops) {
 		entry = create_proc_entry(ACPI_SBS_FILE_INFO, S_IRUGO, *dir);
 		if (!entry) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "create_proc_entry() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"create_proc_entry() failed"));
 		} else {
 			entry->proc_fops = info_fops;
 			entry->data = data;
@@ -898,8 +898,8 @@ acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
 	if (state_fops) {
 		entry = create_proc_entry(ACPI_SBS_FILE_STATE, S_IRUGO, *dir);
 		if (!entry) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "create_proc_entry() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"create_proc_entry() failed"));
 		} else {
 			entry->proc_fops = state_fops;
 			entry->data = data;
@@ -911,8 +911,8 @@ acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
 	if (alarm_fops) {
 		entry = create_proc_entry(ACPI_SBS_FILE_ALARM, S_IRUGO, *dir);
 		if (!entry) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "create_proc_entry() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"create_proc_entry() failed"));
 		} else {
 			entry->proc_fops = alarm_fops;
 			entry->data = data;
@@ -957,8 +957,8 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
 	if (update_mode == REQUEST_UPDATE_MODE) {
 		result = acpi_sbs_update_run(battery->sbs, DATA_TYPE_INFO);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_update_run() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbs_update_run() failed"));
 		}
 	}
 
@@ -1032,8 +1032,8 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
 	if (update_mode == REQUEST_UPDATE_MODE) {
 		result = acpi_sbs_update_run(battery->sbs, DATA_TYPE_STATE);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_update_run() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbs_update_run() failed"));
 		}
 	}
 
@@ -1108,8 +1108,8 @@ static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
 	if (update_mode == REQUEST_UPDATE_MODE) {
 		result = acpi_sbs_update_run(battery->sbs, DATA_TYPE_ALARM);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_update_run() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbs_update_run() failed"));
 		}
 	}
 
@@ -1177,15 +1177,15 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer,
 
 	result = acpi_battery_set_alarm(battery, new_alarm);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_battery_set_alarm() failed\n"));
+		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_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_battery_get_alarm() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_battery_get_alarm() failed"));
 		acpi_battery_set_alarm(battery, old_alarm);
 		goto end;
 	}
@@ -1248,8 +1248,8 @@ static int acpi_ac_read_state(struct seq_file *seq, void *offset)
 	if (update_mode == REQUEST_UPDATE_MODE) {
 		result = acpi_sbs_update_run(sbs, DATA_TYPE_AC_STATE);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_update_run() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbs_update_run() failed"));
 		}
 	}
 
@@ -1297,15 +1297,15 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
 
 	result = acpi_battery_select(battery);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_battery_select() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_battery_select() failed"));
 		goto end;
 	}
 
 	result = acpi_battery_get_present(battery);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_battery_get_present() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_battery_get_present() failed"));
 		goto end;
 	}
 
@@ -1314,8 +1314,8 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
 	if (is_present) {
 		result = acpi_battery_init(battery);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_battery_init() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_battery_init() failed"));
 			goto end;
 		}
 		battery->init_state = 1;
@@ -1330,8 +1330,8 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
 					 &acpi_battery_state_fops,
 					 &acpi_battery_alarm_fops, battery);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_generic_add_fs() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_generic_add_fs() failed"));
 		goto end;
 	}
 	battery->alive = 1;
@@ -1355,8 +1355,8 @@ static int acpi_ac_add(struct acpi_sbs *sbs)
 
 	result = acpi_ac_get_present(sbs);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_ac_get_present() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_ac_get_present() failed"));
 		goto end;
 	}
 
@@ -1365,8 +1365,8 @@ static int acpi_ac_add(struct acpi_sbs *sbs)
 					 ACPI_AC_DIR_NAME,
 					 NULL, &acpi_ac_state_fops, NULL, sbs);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_generic_add_fs() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_generic_add_fs() failed"));
 		goto end;
 	}
 
@@ -1409,8 +1409,8 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
 
 	result = acpi_ac_get_present(sbs);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_ac_get_present() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_ac_get_present() failed"));
 	}
 
 	new_ac_present = acpi_ac_is_present(sbs);
@@ -1433,8 +1433,8 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
 
 		result = acpi_battery_select(battery);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_battery_select() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_battery_select() failed"));
 		}
 		if (sbs->zombie) {
 			goto end;
@@ -1442,8 +1442,8 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
 
 		result = acpi_battery_get_present(battery);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_battery_get_present() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_battery_get_present() failed"));
 		}
 		if (sbs->zombie) {
 			goto end;
@@ -1466,9 +1466,9 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
 			}
 			result = acpi_battery_init(battery);
 			if (result) {
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "acpi_battery_init() "
-						  "failed\n"));
+				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+						"acpi_battery_init() "
+						"failed"));
 			}
 		}
 		if (data_type == DATA_TYPE_INFO) {
@@ -1481,9 +1481,9 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
 		if (new_battery_present) {
 			result = acpi_battery_get_alarm(battery);
 			if (result) {
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "acpi_battery_get_alarm() "
-						  "failed\n"));
+				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+						"acpi_battery_get_alarm() "
+						"failed"));
 			}
 			if (data_type == DATA_TYPE_ALARM) {
 				continue;
@@ -1491,9 +1491,9 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
 
 			result = acpi_battery_get_state(battery);
 			if (result) {
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "acpi_battery_get_state() "
-						  "failed\n"));
+				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+						"acpi_battery_get_state() "
+						"failed"));
 			}
 		}
 		if (sbs->zombie) {
@@ -1511,9 +1511,9 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
 							 dir_name,
 							 ACPI_BATTERY_CLASS);
 			if (result) {
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "acpi_sbs_generate_event() "
-						  "failed\n"));
+				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+						"acpi_sbs_generate_event() "
+						"failed"));
 			}
 		}
 		if (old_remaining_capacity != battery->state.remaining_capacity) {
@@ -1524,8 +1524,8 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
 							 dir_name,
 							 ACPI_BATTERY_CLASS);
 			if (result) {
-				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-						  "acpi_sbs_generate_event() failed\n"));
+				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+						"acpi_sbs_generate_event() failed"));
 			}
 		}
 
@@ -1544,8 +1544,8 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
 						 ACPI_AC_DIR_NAME,
 						 ACPI_AC_CLASS);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbs_generate_event() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbs_generate_event() failed"));
 		}
 	}
 
@@ -1565,8 +1565,8 @@ static void acpi_sbs_update_queue(void *data)
 
 	result = acpi_sbs_update_run(sbs, DATA_TYPE_COMMON);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_sbs_update_run() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_update_run() failed"));
 	}
 
 	if (sbs->zombie) {
@@ -1598,13 +1598,13 @@ static int acpi_sbs_add(struct acpi_device *device)
 	status =
 	    acpi_evaluate_integer(device->parent->handle, "_EC", NULL, &val);
 	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error obtaining _EC\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Error obtaining _EC"));
 		return -EIO;
 	}
 
 	sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL);
 	if (!sbs) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "kmalloc() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "kmalloc() failed"));
 		return -ENOMEM;
 	}
 	sbs->base = (val & 0xff00ull) >> 8;
@@ -1620,13 +1620,13 @@ static int acpi_sbs_add(struct acpi_device *device)
 
 	result = acpi_ac_add(sbs);
 	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "acpi_ac_add() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed"));
 		goto end;
 	}
 	result = acpi_evaluate_integer(device->handle, "_SBS", NULL, &sbs_obj);
 	if (ACPI_FAILURE(result)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_evaluate_integer() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_evaluate_integer() failed"));
 		result = -EIO;
 		goto end;
 	}
@@ -1634,8 +1634,8 @@ static int acpi_sbs_add(struct acpi_device *device)
 	if (sbs_obj > 0) {
 		result = acpi_sbsm_get_info(sbs);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_sbsm_get_info() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbsm_get_info() failed"));
 			goto end;
 		}
 		sbs->sbsm_present = 1;
@@ -1643,8 +1643,8 @@ static int acpi_sbs_add(struct acpi_device *device)
 	if (sbs->sbsm_present == 0) {
 		result = acpi_battery_add(sbs, 0);
 		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_battery_add() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_battery_add() failed"));
 			goto end;
 		}
 	} else {
@@ -1652,9 +1652,9 @@ static int acpi_sbs_add(struct acpi_device *device)
 			if ((sbs->sbsm_batteries_supported & (1 << id))) {
 				result = acpi_battery_add(sbs, id);
 				if (result) {
-					ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-							  "acpi_battery_add() "
-							  "failed\n"));
+					ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+							"acpi_battery_add() "
+							"failed"));
 					goto end;
 				}
 			}
@@ -1668,8 +1668,8 @@ static int acpi_sbs_add(struct acpi_device *device)
 		status = acpi_os_execute(OSL_GPE_HANDLER,
 					 acpi_sbs_update_queue, sbs);
 		if (status != AE_OK) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-					  "acpi_os_execute() failed\n"));
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_os_execute() failed"));
 		}
 	}
 	sbs->update_time = update_time;
@@ -1733,30 +1733,29 @@ static int __init acpi_sbs_init(void)
 	if (capacity_mode != DEF_CAPACITY_UNIT
 	    && capacity_mode != MAH_CAPACITY_UNIT
 	    && capacity_mode != MWH_CAPACITY_UNIT) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "acpi_sbs_init: "
-				  "invalid capacity_mode = %d\n",
-				  capacity_mode));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_sbs_init: "
+				"invalid capacity_mode = %d", capacity_mode));
 		return -EINVAL;
 	}
 
 	acpi_ac_dir = acpi_lock_ac_dir();
 	if (!acpi_ac_dir) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_lock_ac_dir() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_lock_ac_dir() failed"));
 		return -ENODEV;
 	}
 
 	acpi_battery_dir = acpi_lock_battery_dir();
 	if (!acpi_battery_dir) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_lock_battery_dir() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_lock_battery_dir() failed"));
 		return -ENODEV;
 	}
 
 	result = acpi_bus_register_driver(&acpi_sbs_driver);
 	if (result < 0) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "acpi_bus_register_driver() failed\n"));
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_bus_register_driver() failed"));
 		return -ENODEV;
 	}
 
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 022/105] ACPI: sbs: Common interface with CM battery
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Vladimir Lebedev, Len Brown

From: Vladimir Lebedev <vladimir.p.lebedev@intel.com>

The SBS driver has tne features as CM battery:
SBS update_time variable has tne same definition as CM battery 'update_time' variable.

Signed-off-by: Vladimir Lebedev <vladimir.p.lebedev@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/sbs.c |  577 +++++++++++++++++++++++++++++-----------------------
 1 files changed, 319 insertions(+), 258 deletions(-)

diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 3956645..c1bae10 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -31,6 +31,7 @@
 #include <asm/uaccess.h>
 #include <linux/acpi.h>
 #include <linux/timer.h>
+#include <linux/jiffies.h>
 #include <linux/delay.h>
 
 #define ACPI_SBS_COMPONENT		0x00080000
@@ -109,29 +110,19 @@ extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
 #define ACPI_SBS_WORD_DATA		1
 #define ACPI_SBS_BLOCK_DATA		2
 
-static struct semaphore sbs_sem;
+#define	UPDATE_DELAY	10
 
-#define	UPDATE_MODE		QUEUE_UPDATE_MODE
-/* REQUEST_UPDATE_MODE  QUEUE_UPDATE_MODE */
-#define	UPDATE_INFO_MODE	0
-#define	UPDATE_TIME		60
-#define	UPDATE_TIME2		0
+/* 0 - every time, > 0 - by update_time */
+static unsigned int update_time = 120;
 
-static int capacity_mode = CAPACITY_UNIT;
-static int update_mode = UPDATE_MODE;
-static int update_info_mode = UPDATE_INFO_MODE;
-static int update_time = UPDATE_TIME;
-static int update_time2 = UPDATE_TIME2;
+static unsigned int capacity_mode = CAPACITY_UNIT;
 
-module_param(capacity_mode, int, 0);
-module_param(update_mode, int, 0);
-module_param(update_info_mode, int, 0);
-module_param(update_time, int, 0);
-module_param(update_time2, int, 0);
+module_param(update_time, uint, 0644);
+module_param(capacity_mode, uint, 0444);
 
 static int acpi_sbs_add(struct acpi_device *device);
 static int acpi_sbs_remove(struct acpi_device *device, int type);
-static void acpi_sbs_update_queue(void *data);
+static int acpi_sbs_resume(struct acpi_device *device);
 
 static struct acpi_driver acpi_sbs_driver = {
 	.name = "sbs",
@@ -140,9 +131,14 @@ static struct acpi_driver acpi_sbs_driver = {
 	.ops = {
 		.add = acpi_sbs_add,
 		.remove = acpi_sbs_remove,
+		.resume = acpi_sbs_resume,
 		},
 };
 
+struct acpi_ac {
+	int ac_present;
+};
+
 struct acpi_battery_info {
 	int capacity_mode;
 	s16 full_charge_capacity;
@@ -160,9 +156,7 @@ struct acpi_battery_state {
 	s16 voltage;
 	s16 amperage;
 	s16 remaining_capacity;
-	s16 average_time_to_empty;
-	s16 average_time_to_full;
-	s16 battery_status;
+	s16 battery_state;
 };
 
 struct acpi_battery_alarm {
@@ -171,9 +165,9 @@ struct acpi_battery_alarm {
 
 struct acpi_battery {
 	int alive;
-	int battery_present;
 	int id;
 	int init_state;
+	int battery_present;
 	struct acpi_sbs *sbs;
 	struct acpi_battery_info info;
 	struct acpi_battery_state state;
@@ -185,18 +179,22 @@ struct acpi_sbs {
 	acpi_handle handle;
 	int base;
 	struct acpi_device *device;
+	struct acpi_ec_smbus *smbus;
+	struct mutex mutex;
 	int sbsm_present;
 	int sbsm_batteries_supported;
-	int ac_present;
 	struct proc_dir_entry *ac_entry;
+	struct acpi_ac ac;
 	struct acpi_battery battery[MAX_SBS_BAT];
-	int update_info_mode;
 	int zombie;
-	int update_time;
-	int update_time2;
 	struct timer_list update_timer;
+	int run_cnt;
+	int update_proc_flg;
 };
 
+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];
@@ -205,8 +203,6 @@ union sbs_rw_data {
 static int acpi_ec_sbs_access(struct acpi_sbs *sbs, u16 addr,
 			      char read_write, u8 command, int size,
 			      union sbs_rw_data *data);
-static void acpi_update_delay(struct acpi_sbs *sbs);
-static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type);
 
 /* --------------------------------------------------------------------------
                                SMBus Communication
@@ -383,11 +379,49 @@ acpi_sbs_write_word(struct acpi_sbs *sbs, int addr, int func, int word)
 	return result;
 }
 
+static int sbs_zombie(struct acpi_sbs *sbs)
+{
+	return (sbs->zombie);
+}
+
+static int sbs_mutex_lock(struct acpi_sbs *sbs)
+{
+	if (sbs_zombie(sbs)) {
+		return -ENODEV;
+	}
+	mutex_lock(&sbs->mutex);
+	return 0;
+}
+
+static void sbs_mutex_unlock(struct acpi_sbs *sbs)
+{
+	mutex_unlock(&sbs->mutex);
+}
+
 /* --------------------------------------------------------------------------
                             Smart Battery System Management
    -------------------------------------------------------------------------- */
 
-/* Smart Battery */
+static int acpi_check_update_proc(struct acpi_sbs *sbs)
+{
+	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;
+}
 
 static int acpi_sbs_generate_event(struct acpi_device *device,
 				   int event, int state, char *bid, char *class)
@@ -430,16 +464,6 @@ static int acpi_battery_get_present(struct acpi_battery *battery)
 	return result;
 }
 
-static int acpi_battery_is_present(struct acpi_battery *battery)
-{
-	return (battery->battery_present);
-}
-
-static int acpi_ac_is_present(struct acpi_sbs *sbs)
-{
-	return (sbs->ac_present);
-}
-
 static int acpi_battery_select(struct acpi_battery *battery)
 {
 	struct acpi_sbs *sbs = battery->sbs;
@@ -447,7 +471,7 @@ static int acpi_battery_select(struct acpi_battery *battery)
 	s16 state;
 	int foo;
 
-	if (battery->sbs->sbsm_present) {
+	if (sbs->sbsm_present) {
 
 		/* Take special care not to knobble other nibbles of
 		 * state (aka selector_state), since
@@ -523,6 +547,8 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 				    &battery->info.design_capacity);
 
 	if (result) {
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_read_word() failed"));
 		goto end;
 	}
 
@@ -573,6 +599,8 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1c,
 				    &battery->info.serial_number);
 	if (result) {
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+				"acpi_sbs_read_word() failed"));
 		goto end;
 	}
 
@@ -604,22 +632,11 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 	return result;
 }
 
-static void acpi_update_delay(struct acpi_sbs *sbs)
-{
-	if (sbs->zombie) {
-		return;
-	}
-	if (sbs->update_time2 > 0) {
-		msleep(sbs->update_time2 * 1000);
-	}
-}
-
 static int acpi_battery_get_state(struct acpi_battery *battery)
 {
 	struct acpi_sbs *sbs = battery->sbs;
 	int result = 0;
 
-	acpi_update_delay(battery->sbs);
 	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x09,
 				    &battery->state.voltage);
 	if (result) {
@@ -628,7 +645,6 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 		goto end;
 	}
 
-	acpi_update_delay(battery->sbs);
 	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0a,
 				    &battery->state.amperage);
 	if (result) {
@@ -637,7 +653,6 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 		goto end;
 	}
 
-	acpi_update_delay(battery->sbs);
 	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0f,
 				    &battery->state.remaining_capacity);
 	if (result) {
@@ -646,35 +661,14 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
 		goto end;
 	}
 
-	acpi_update_delay(battery->sbs);
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x12,
-				    &battery->state.average_time_to_empty);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
-		goto end;
-	}
-
-	acpi_update_delay(battery->sbs);
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x13,
-				    &battery->state.average_time_to_full);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
-		goto end;
-	}
-
-	acpi_update_delay(battery->sbs);
 	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x16,
-				    &battery->state.battery_status);
+				    &battery->state.battery_state);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 				"acpi_sbs_read_word() failed"));
 		goto end;
 	}
 
-	acpi_update_delay(battery->sbs);
-
       end:
 	return result;
 }
@@ -692,8 +686,6 @@ static int acpi_battery_get_alarm(struct acpi_battery *battery)
 		goto end;
 	}
 
-	acpi_update_delay(battery->sbs);
-
       end:
 
 	return result;
@@ -751,6 +743,7 @@ 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;
 
@@ -758,7 +751,7 @@ static int acpi_battery_set_mode(struct acpi_battery *battery)
 		goto end;
 	}
 
-	result = acpi_sbs_read_word(battery->sbs,
+	result = acpi_sbs_read_word(sbs,
 				    ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -771,7 +764,7 @@ static int acpi_battery_set_mode(struct acpi_battery *battery)
 	} else {
 		battery_mode |= 0x8000;
 	}
-	result = acpi_sbs_write_word(battery->sbs,
+	result = acpi_sbs_write_word(sbs,
 				     ACPI_SB_SMBUS_ADDR, 0x03, battery_mode);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -779,7 +772,7 @@ static int acpi_battery_set_mode(struct acpi_battery *battery)
 		goto end;
 	}
 
-	result = acpi_sbs_read_word(battery->sbs,
+	result = acpi_sbs_read_word(sbs,
 				    ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -798,7 +791,7 @@ static int acpi_battery_init(struct acpi_battery *battery)
 	result = acpi_battery_select(battery);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_battery_init() failed"));
+				"acpi_battery_select() failed"));
 		goto end;
 	}
 
@@ -848,7 +841,7 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)
 		goto end;
 	}
 
-	sbs->ac_present = (charger_status & 0x8000) >> 15;
+	sbs->ac.ac_present = (charger_status & 0x8000) >> 15;
 
       end:
 
@@ -945,24 +938,27 @@ static struct proc_dir_entry *acpi_battery_dir = NULL;
 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 (battery->sbs->zombie) {
+	if (sbs_mutex_lock(sbs)) {
 		return -ENODEV;
 	}
 
-	down(&sbs_sem);
+	result = acpi_check_update_proc(sbs);
+	if (result)
+		goto end;
 
-	if (update_mode == REQUEST_UPDATE_MODE) {
-		result = acpi_sbs_update_run(battery->sbs, DATA_TYPE_INFO);
+	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 (acpi_battery_is_present(battery)) {
+	if (battery->battery_present) {
 		seq_printf(seq, "present:                 yes\n");
 	} else {
 		seq_printf(seq, "present:                 no\n");
@@ -974,13 +970,13 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
 	} else {
 		cscale = battery->info.ipscale;
 	}
-	seq_printf(seq, "design capacity:         %i%s",
+	seq_printf(seq, "design capacity:         %i%s\n",
 		   battery->info.design_capacity * cscale,
-		   battery->info.capacity_mode ? "0 mWh\n" : " mAh\n");
+		   battery->info.capacity_mode ? "0 mWh" : " mAh");
 
-	seq_printf(seq, "last full capacity:      %i%s",
+	seq_printf(seq, "last full capacity:      %i%s\n",
 		   battery->info.full_charge_capacity * cscale,
-		   battery->info.capacity_mode ? "0 mWh\n" : " mAh\n");
+		   battery->info.capacity_mode ? "0 mWh" : " mAh");
 
 	seq_printf(seq, "battery technology:      rechargeable\n");
 
@@ -1006,7 +1002,7 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
 
       end:
 
-	up(&sbs_sem);
+	sbs_mutex_unlock(sbs);
 
 	return result;
 }
@@ -1018,26 +1014,29 @@ static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
 
 static int acpi_battery_read_state(struct seq_file *seq, void *offset)
 {
-	struct acpi_battery *battery = (struct acpi_battery *)seq->private;
+	struct acpi_battery *battery = seq->private;
+	struct acpi_sbs *sbs = battery->sbs;
 	int result = 0;
 	int cscale;
 	int foo;
 
-	if (battery->sbs->zombie) {
+	if (sbs_mutex_lock(sbs)) {
 		return -ENODEV;
 	}
 
-	down(&sbs_sem);
+	result = acpi_check_update_proc(sbs);
+	if (result)
+		goto end;
 
-	if (update_mode == REQUEST_UPDATE_MODE) {
-		result = acpi_sbs_update_run(battery->sbs, DATA_TYPE_STATE);
+	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 (acpi_battery_is_present(battery)) {
+	if (battery->battery_present) {
 		seq_printf(seq, "present:                 yes\n");
 	} else {
 		seq_printf(seq, "present:                 no\n");
@@ -1050,7 +1049,7 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
 		cscale = battery->info.ipscale;
 	}
 
-	if (battery->state.battery_status & 0x0010) {
+	if (battery->state.battery_state & 0x0010) {
 		seq_printf(seq, "capacity state:          critical\n");
 	} else {
 		seq_printf(seq, "capacity state:          ok\n");
@@ -1074,16 +1073,16 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
 			   battery->info.capacity_mode ? "mW" : "mA");
 	}
 
-	seq_printf(seq, "remaining capacity:      %i%s",
+	seq_printf(seq, "remaining capacity:      %i%s\n",
 		   battery->state.remaining_capacity * cscale,
-		   battery->info.capacity_mode ? "0 mWh\n" : " mAh\n");
+		   battery->info.capacity_mode ? "0 mWh" : " mAh");
 
 	seq_printf(seq, "present voltage:         %i mV\n",
 		   battery->state.voltage * battery->info.vscale);
 
       end:
 
-	up(&sbs_sem);
+	sbs_mutex_unlock(sbs);
 
 	return result;
 }
@@ -1096,24 +1095,27 @@ static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
 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 (battery->sbs->zombie) {
+	if (sbs_mutex_lock(sbs)) {
 		return -ENODEV;
 	}
 
-	down(&sbs_sem);
+	result = acpi_check_update_proc(sbs);
+	if (result)
+		goto end;
 
-	if (update_mode == REQUEST_UPDATE_MODE) {
-		result = acpi_sbs_update_run(battery->sbs, DATA_TYPE_ALARM);
+	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"));
 		}
 	}
 
-	if (!acpi_battery_is_present(battery)) {
+	if (!battery->battery_present) {
 		seq_printf(seq, "present:                 no\n");
 		goto end;
 	}
@@ -1126,16 +1128,16 @@ static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
 
 	seq_printf(seq, "alarm:                   ");
 	if (battery->alarm.remaining_capacity) {
-		seq_printf(seq, "%i%s",
+		seq_printf(seq, "%i%s\n",
 			   battery->alarm.remaining_capacity * cscale,
-			   battery->info.capacity_mode ? "0 mWh\n" : " mAh\n");
+			   battery->info.capacity_mode ? "0 mWh" : " mAh");
 	} else {
 		seq_printf(seq, "disabled\n");
 	}
 
       end:
 
-	up(&sbs_sem);
+	sbs_mutex_unlock(sbs);
 
 	return result;
 }
@@ -1146,16 +1148,19 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer,
 {
 	struct seq_file *seq = file->private_data;
 	struct acpi_battery *battery = seq->private;
+	struct acpi_sbs *sbs = battery->sbs;
 	char alarm_string[12] = { '\0' };
 	int result, old_alarm, new_alarm;
 
-	if (battery->sbs->zombie) {
+	if (sbs_mutex_lock(sbs)) {
 		return -ENODEV;
 	}
 
-	down(&sbs_sem);
+	result = acpi_check_update_proc(sbs);
+	if (result)
+		goto end;
 
-	if (!acpi_battery_is_present(battery)) {
+	if (!battery->battery_present) {
 		result = -ENODEV;
 		goto end;
 	}
@@ -1191,7 +1196,7 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer,
 	}
 
       end:
-	up(&sbs_sem);
+	sbs_mutex_unlock(sbs);
 
 	if (result) {
 		return result;
@@ -1239,14 +1244,12 @@ static int acpi_ac_read_state(struct seq_file *seq, void *offset)
 	struct acpi_sbs *sbs = seq->private;
 	int result;
 
-	if (sbs->zombie) {
+	if (sbs_mutex_lock(sbs)) {
 		return -ENODEV;
 	}
 
-	down(&sbs_sem);
-
-	if (update_mode == REQUEST_UPDATE_MODE) {
-		result = acpi_sbs_update_run(sbs, DATA_TYPE_AC_STATE);
+	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"));
@@ -1254,9 +1257,9 @@ static int acpi_ac_read_state(struct seq_file *seq, void *offset)
 	}
 
 	seq_printf(seq, "state:                   %s\n",
-		   sbs->ac_present ? "on-line" : "off-line");
+		   sbs->ac.ac_present ? "on-line" : "off-line");
 
-	up(&sbs_sem);
+	sbs_mutex_unlock(sbs);
 
 	return 0;
 }
@@ -1309,7 +1312,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
 		goto end;
 	}
 
-	is_present = acpi_battery_is_present(battery);
+	is_present = battery->battery_present;
 
 	if (is_present) {
 		result = acpi_battery_init(battery);
@@ -1336,6 +1339,10 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
 	}
 	battery->alive = 1;
 
+	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");
+
       end:
 	return result;
 }
@@ -1370,6 +1377,10 @@ static int acpi_ac_add(struct acpi_sbs *sbs)
 		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->ac.ac_present ? "on-line" : "off-line");
+
       end:
 
 	return result;
@@ -1383,29 +1394,48 @@ static void acpi_ac_remove(struct acpi_sbs *sbs)
 	}
 }
 
-static void acpi_sbs_update_queue_run(unsigned long data)
+static void acpi_sbs_update_time_run(unsigned long data)
 {
-	acpi_os_execute(OSL_GPE_HANDLER, acpi_sbs_update_queue, (void *)data);
+	acpi_os_execute(OSL_GPE_HANDLER, acpi_sbs_update_time, (void *)data);
 }
 
-static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
+static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)
 {
 	struct acpi_battery *battery;
-	int result = 0;
-	int old_ac_present;
-	int old_battery_present;
-	int new_ac_present;
-	int new_battery_present;
-	int id;
+	int result = 0, cnt;
+	int old_ac_present = -1;
+	int old_battery_present = -1;
+	int new_ac_present = -1;
+	int new_battery_present = -1;
+	int id_min = 0, id_max = MAX_SBS_BAT - 1;
 	char dir_name[32];
-	int do_battery_init, do_ac_init;
-	s16 old_remaining_capacity;
+	int do_battery_init = 0, do_ac_init = 0;
+	int old_remaining_capacity = 0;
+	int update_ac = 1, update_battery = 1;
+	int up_tm = update_time;
+
+	if (sbs_zombie(sbs)) {
+		goto end;
+	}
 
-	if (sbs->zombie) {
+	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_ac && !update_battery) {
 		goto end;
 	}
 
-	old_ac_present = acpi_ac_is_present(sbs);
+	old_ac_present = sbs->ac.ac_present;
 
 	result = acpi_ac_get_present(sbs);
 	if (result) {
@@ -1413,15 +1443,36 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
 				"acpi_ac_get_present() failed"));
 	}
 
-	new_ac_present = acpi_ac_is_present(sbs);
+	new_ac_present = sbs->ac.ac_present;
 
 	do_ac_init = (old_ac_present != new_ac_present);
+	if (sbs->run_cnt == 1 && data_type == DATA_TYPE_COMMON) {
+		do_ac_init = 1;
+	}
 
-	if (data_type == DATA_TYPE_AC_STATE) {
+	if (do_ac_init) {
+		result = acpi_sbs_generate_event(sbs->device,
+						 ACPI_SBS_AC_NOTIFY_STATUS,
+						 new_ac_present,
+						 ACPI_AC_DIR_NAME,
+						 ACPI_AC_CLASS);
+		if (result) {
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbs_generate_event() failed"));
+		}
+	}
+
+	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;
 	}
 
-	for (id = 0; id < MAX_SBS_BAT; id++) {
+	for (id = id_min; id <= id_max; id++) {
 		battery = &sbs->battery[id];
 		if (battery->alive == 0) {
 			continue;
@@ -1429,41 +1480,27 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
 
 		old_remaining_capacity = battery->state.remaining_capacity;
 
-		old_battery_present = acpi_battery_is_present(battery);
+		old_battery_present = battery->battery_present;
 
 		result = acpi_battery_select(battery);
 		if (result) {
 			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 					"acpi_battery_select() failed"));
 		}
-		if (sbs->zombie) {
-			goto end;
-		}
 
 		result = acpi_battery_get_present(battery);
 		if (result) {
 			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 					"acpi_battery_get_present() failed"));
 		}
-		if (sbs->zombie) {
-			goto end;
-		}
 
-		new_battery_present = acpi_battery_is_present(battery);
+		new_battery_present = battery->battery_present;
 
 		do_battery_init = ((old_battery_present != new_battery_present)
 				   && new_battery_present);
-
-		if (sbs->zombie) {
-			goto end;
-		}
-		if (do_ac_init || do_battery_init ||
-		    update_info_mode || sbs->update_info_mode) {
-			if (sbs->update_info_mode) {
-				sbs->update_info_mode = 0;
-			} else {
-				sbs->update_info_mode = 1;
-			}
+		if (!new_battery_present)
+			goto event;
+		if (do_ac_init || do_battery_init) {
 			result = acpi_battery_init(battery);
 			if (result) {
 				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -1471,52 +1508,64 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
 						"failed"));
 			}
 		}
-		if (data_type == DATA_TYPE_INFO) {
-			continue;
-		}
-
-		if (sbs->zombie) {
+		if (sbs_zombie(sbs)) {
 			goto end;
 		}
-		if (new_battery_present) {
-			result = acpi_battery_get_alarm(battery);
+
+		if ((data_type == DATA_TYPE_COMMON
+		     || data_type == DATA_TYPE_INFO)
+		    && new_battery_present) {
+			result = acpi_battery_get_info(battery);
 			if (result) {
 				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-						"acpi_battery_get_alarm() "
-						"failed"));
-			}
-			if (data_type == DATA_TYPE_ALARM) {
-				continue;
+						"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_battery_present) {
 			result = acpi_battery_get_state(battery);
 			if (result) {
 				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-						"acpi_battery_get_state() "
-						"failed"));
+						"acpi_battery_get_state() failed"));
 			}
 		}
-		if (sbs->zombie) {
-			goto end;
+		if (data_type == DATA_TYPE_STATE) {
+			goto event;
 		}
-		if (data_type != DATA_TYPE_COMMON) {
-			continue;
+		if (sbs_zombie(sbs)) {
+			goto end;
 		}
 
-		if (old_battery_present != new_battery_present) {
-			sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
-			result = acpi_sbs_generate_event(sbs->device,
-							 ACPI_SBS_BATTERY_NOTIFY_STATUS,
-							 new_battery_present,
-							 dir_name,
-							 ACPI_BATTERY_CLASS);
+		if ((data_type == DATA_TYPE_COMMON
+		     || data_type == DATA_TYPE_ALARM)
+		    && new_battery_present) {
+			result = acpi_battery_get_alarm(battery);
 			if (result) {
 				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-						"acpi_sbs_generate_event() "
+						"acpi_battery_get_alarm() "
 						"failed"));
 			}
 		}
-		if (old_remaining_capacity != battery->state.remaining_capacity) {
+		if (data_type == DATA_TYPE_ALARM) {
+			continue;
+		}
+		if (sbs_zombie(sbs)) {
+			goto end;
+		}
+
+	      event:
+
+		if (old_battery_present != new_battery_present || do_ac_init ||
+		    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,
@@ -1525,71 +1574,62 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
 							 ACPI_BATTERY_CLASS);
 			if (result) {
 				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-						"acpi_sbs_generate_event() failed"));
+						"acpi_sbs_generate_event() "
+						"failed"));
 			}
 		}
-
-	}
-	if (sbs->zombie) {
-		goto end;
-	}
-	if (data_type != DATA_TYPE_COMMON) {
-		goto end;
-	}
-
-	if (old_ac_present != new_ac_present) {
-		result = acpi_sbs_generate_event(sbs->device,
-						 ACPI_SBS_AC_NOTIFY_STATUS,
-						 new_ac_present,
-						 ACPI_AC_DIR_NAME,
-						 ACPI_AC_CLASS);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_sbs_generate_event() failed"));
-		}
 	}
 
       end:
+
 	return result;
 }
 
-static void acpi_sbs_update_queue(void *data)
+static void acpi_sbs_update_time(void *data)
 {
 	struct acpi_sbs *sbs = data;
 	unsigned long delay = -1;
 	int result;
+	unsigned int up_tm = update_time;
 
-	if (sbs->zombie) {
-		goto end;
-	}
+	if (sbs_mutex_lock(sbs))
+		return;
 
-	result = acpi_sbs_update_run(sbs, DATA_TYPE_COMMON);
+	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) {
+	if (sbs_zombie(sbs)) {
 		goto end;
 	}
 
-	if (update_mode == REQUEST_UPDATE_MODE) {
-		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);
+		}
 	}
 
-	delay = jiffies + HZ * update_time;
-	sbs->update_timer.data = (unsigned long)data;
-	sbs->update_timer.function = acpi_sbs_update_queue_run;
-	sbs->update_timer.expires = delay;
-	add_timer(&sbs->update_timer);
       end:
-	;
+
+	sbs_mutex_unlock(sbs);
 }
 
 static int acpi_sbs_add(struct acpi_device *device)
 {
 	struct acpi_sbs *sbs = NULL;
-	int result;
+	int result = 0, remove_result = 0;
 	unsigned long sbs_obj;
 	int id;
 	acpi_status status = AE_OK;
@@ -1604,33 +1644,34 @@ static int acpi_sbs_add(struct acpi_device *device)
 
 	sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL);
 	if (!sbs) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "kmalloc() failed"));
-		return -ENOMEM;
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "kzalloc() failed"));
+		result = -ENOMEM;
+		goto end;
 	}
-	sbs->base = (val & 0xff00ull) >> 8;
 
+	mutex_init(&sbs->mutex);
+
+	sbs_mutex_lock(sbs);
+
+	sbs->base = (val & 0xff00ull) >> 8;
 	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;
 
-	sbs->update_time = 0;
-	sbs->update_time2 = 0;
-
 	result = acpi_ac_add(sbs);
 	if (result) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed"));
 		goto end;
 	}
-	result = acpi_evaluate_integer(device->handle, "_SBS", NULL, &sbs_obj);
-	if (ACPI_FAILURE(result)) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+	status = acpi_evaluate_integer(device->handle, "_SBS", NULL, &sbs_obj);
+	if (status) {
+		ACPI_EXCEPTION((AE_INFO, status,
 				"acpi_evaluate_integer() failed"));
 		result = -EIO;
 		goto end;
 	}
-
 	if (sbs_obj > 0) {
 		result = acpi_sbsm_get_info(sbs);
 		if (result) {
@@ -1640,6 +1681,7 @@ static int acpi_sbs_add(struct acpi_device *device)
 		}
 		sbs->sbsm_present = 1;
 	}
+
 	if (sbs->sbsm_present == 0) {
 		result = acpi_battery_add(sbs, 0);
 		if (result) {
@@ -1653,8 +1695,7 @@ static int acpi_sbs_add(struct acpi_device *device)
 				result = acpi_battery_add(sbs, id);
 				if (result) {
 					ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-							"acpi_battery_add() "
-							"failed"));
+							"acpi_battery_add() failed"));
 					goto end;
 				}
 			}
@@ -1664,29 +1705,26 @@ static int acpi_sbs_add(struct acpi_device *device)
 	sbs->handle = device->handle;
 
 	init_timer(&sbs->update_timer);
-	if (update_mode == QUEUE_UPDATE_MODE) {
-		status = acpi_os_execute(OSL_GPE_HANDLER,
-					 acpi_sbs_update_queue, sbs);
-		if (status != AE_OK) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_os_execute() failed"));
-		}
-	}
-	sbs->update_time = update_time;
-	sbs->update_time2 = update_time2;
-
-	printk(KERN_INFO PREFIX "%s [%s]\n",
-	       acpi_device_name(device), acpi_device_bid(device));
+	result = acpi_check_update_proc(sbs);
+	if (result)
+		goto end;
 
       end:
+
+	sbs_mutex_unlock(sbs);
+
 	if (result) {
-		acpi_sbs_remove(device, 0);
+		remove_result = acpi_sbs_remove(device, 0);
+		if (remove_result) {
+			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+					"acpi_sbs_remove() failed"));
+		}
 	}
 
 	return result;
 }
 
-int acpi_sbs_remove(struct acpi_device *device, int type)
+static int acpi_sbs_remove(struct acpi_device *device, int type)
 {
 	struct acpi_sbs *sbs;
 	int id;
@@ -1695,15 +1733,14 @@ int acpi_sbs_remove(struct acpi_device *device, int type)
 		return -EINVAL;
 	}
 
-	sbs = (struct acpi_sbs *)acpi_driver_data(device);
-
+	sbs = acpi_driver_data(device);
 	if (!sbs) {
 		return -EINVAL;
 	}
 
+	sbs_mutex_lock(sbs);
+
 	sbs->zombie = 1;
-	sbs->update_time = 0;
-	sbs->update_time2 = 0;
 	del_timer_sync(&sbs->update_timer);
 	acpi_os_wait_events_complete(NULL);
 	del_timer_sync(&sbs->update_timer);
@@ -1714,13 +1751,41 @@ int acpi_sbs_remove(struct acpi_device *device, int type)
 
 	acpi_ac_remove(sbs);
 
-	acpi_driver_data(device) = NULL;
+	sbs_mutex_unlock(sbs);
+
+	mutex_destroy(&sbs->mutex);
 
 	kfree(sbs);
 
 	return 0;
 }
 
+static void acpi_sbs_rmdirs(void)
+{
+	if (acpi_ac_dir) {
+		acpi_unlock_ac_dir(acpi_ac_dir);
+		acpi_ac_dir = NULL;
+	}
+	if (acpi_battery_dir) {
+		acpi_unlock_battery_dir(acpi_battery_dir);
+		acpi_battery_dir = NULL;
+	}
+}
+
+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;
+
+	return 0;
+}
+
 static int __init acpi_sbs_init(void)
 {
 	int result = 0;
@@ -1728,12 +1793,10 @@ static int __init acpi_sbs_init(void)
 	if (acpi_disabled)
 		return -ENODEV;
 
-	init_MUTEX(&sbs_sem);
-
 	if (capacity_mode != DEF_CAPACITY_UNIT
 	    && capacity_mode != MAH_CAPACITY_UNIT
 	    && capacity_mode != MWH_CAPACITY_UNIT) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_sbs_init: "
+		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 				"invalid capacity_mode = %d", capacity_mode));
 		return -EINVAL;
 	}
@@ -1749,6 +1812,7 @@ static int __init acpi_sbs_init(void)
 	if (!acpi_battery_dir) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 				"acpi_lock_battery_dir() failed"));
+		acpi_sbs_rmdirs();
 		return -ENODEV;
 	}
 
@@ -1756,6 +1820,7 @@ static int __init acpi_sbs_init(void)
 	if (result < 0) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
 				"acpi_bus_register_driver() failed"));
+		acpi_sbs_rmdirs();
 		return -ENODEV;
 	}
 
@@ -1764,13 +1829,9 @@ static int __init acpi_sbs_init(void)
 
 static void __exit acpi_sbs_exit(void)
 {
-
 	acpi_bus_unregister_driver(&acpi_sbs_driver);
 
-	acpi_unlock_ac_dir(acpi_ac_dir);
-	acpi_ac_dir = NULL;
-	acpi_unlock_battery_dir(acpi_battery_dir);
-	acpi_battery_dir = NULL;
+	acpi_sbs_rmdirs();
 
 	return;
 }
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 023/105] ACPI: sbs: remove i2c_ec.[ch]
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Len Brown

Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/i2c_ec.c |  403 -------------------------------------------------
 drivers/acpi/i2c_ec.h |   23 ---
 2 files changed, 0 insertions(+), 426 deletions(-)
 delete mode 100644 drivers/acpi/i2c_ec.c
 delete mode 100644 drivers/acpi/i2c_ec.h

diff --git a/drivers/acpi/i2c_ec.c b/drivers/acpi/i2c_ec.c
deleted file mode 100644
index acab4a4..0000000
--- a/drivers/acpi/i2c_ec.c
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * SMBus driver for ACPI Embedded Controller ($Revision: 1.3 $)
- *
- * Copyright (c) 2002, 2005 Ducrot Bruno
- * Copyright (c) 2005 Rich Townsend (tiny hacks & tweaks)
- *
- * 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 <linux/version.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/stddef.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/acpi.h>
-#include <linux/delay.h>
-
-#include "i2c_ec.h"
-
-#define	xudelay(t)	udelay(t)
-#define	xmsleep(t)	msleep(t)
-
-#define ACPI_EC_HC_COMPONENT	0x00080000
-#define ACPI_EC_HC_CLASS	"ec_hc_smbus"
-#define ACPI_EC_HC_HID		"ACPI0001"
-#define ACPI_EC_HC_DEVICE_NAME	"EC HC smbus"
-
-#define _COMPONENT		ACPI_EC_HC_COMPONENT
-
-ACPI_MODULE_NAME("i2c_ec");
-
-static int acpi_ec_hc_add(struct acpi_device *device);
-static int acpi_ec_hc_remove(struct acpi_device *device, int type);
-
-static struct acpi_driver acpi_ec_hc_driver = {
-	.name = "i2c_ec",
-	.class = ACPI_EC_HC_CLASS,
-	.ids = ACPI_EC_HC_HID,
-	.ops = {
-		.add = acpi_ec_hc_add,
-		.remove = acpi_ec_hc_remove,
-		},
-};
-
-/* Various bit mask for EC_SC (R) */
-#define OBF		0x01
-#define IBF		0x02
-#define CMD		0x08
-#define BURST		0x10
-#define SCI_EVT		0x20
-#define SMI_EVT		0x40
-
-/* Commands for EC_SC (W) */
-#define RD_EC		0x80
-#define WR_EC		0x81
-#define BE_EC		0x82
-#define BD_EC		0x83
-#define QR_EC		0x84
-
-/*
- * ACPI 2.0 chapter 13 SMBus 2.0 EC register model
- */
-
-#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_ALRM_A	0x25	/* alarm address */
-#define ACPI_EC_SMB_ALRM_D	0x26	/* 2 bytes alarm data */
-
-#define ACPI_EC_SMB_STS_DONE	0x80
-#define ACPI_EC_SMB_STS_ALRM	0x40
-#define ACPI_EC_SMB_STS_RES	0x20
-#define ACPI_EC_SMB_STS_STATUS	0x1f
-
-#define ACPI_EC_SMB_STATUS_OK		0x00
-#define ACPI_EC_SMB_STATUS_FAIL		0x07
-#define ACPI_EC_SMB_STATUS_DNAK		0x10
-#define ACPI_EC_SMB_STATUS_DERR		0x11
-#define ACPI_EC_SMB_STATUS_CMD_DENY	0x12
-#define ACPI_EC_SMB_STATUS_UNKNOWN	0x13
-#define ACPI_EC_SMB_STATUS_ACC_DENY	0x17
-#define ACPI_EC_SMB_STATUS_TIMEOUT	0x18
-#define ACPI_EC_SMB_STATUS_NOTSUP	0x19
-#define ACPI_EC_SMB_STATUS_BUSY		0x1A
-#define ACPI_EC_SMB_STATUS_PEC		0x1F
-
-#define ACPI_EC_SMB_PRTCL_WRITE			0x00
-#define ACPI_EC_SMB_PRTCL_READ			0x01
-#define ACPI_EC_SMB_PRTCL_QUICK			0x02
-#define ACPI_EC_SMB_PRTCL_BYTE			0x04
-#define ACPI_EC_SMB_PRTCL_BYTE_DATA		0x06
-#define ACPI_EC_SMB_PRTCL_WORD_DATA		0x08
-#define ACPI_EC_SMB_PRTCL_BLOCK_DATA		0x0a
-#define ACPI_EC_SMB_PRTCL_PROC_CALL		0x0c
-#define ACPI_EC_SMB_PRTCL_BLOCK_PROC_CALL	0x0d
-#define ACPI_EC_SMB_PRTCL_I2C_BLOCK_DATA	0x4a
-#define ACPI_EC_SMB_PRTCL_PEC			0x80
-
-/* Length of pre/post transaction sleep (msec) */
-#define ACPI_EC_SMB_TRANSACTION_SLEEP		1
-#define ACPI_EC_SMB_ACCESS_SLEEP1		1
-#define ACPI_EC_SMB_ACCESS_SLEEP2		10
-
-static int acpi_ec_smb_read(struct acpi_ec_smbus *smbus, u8 address, u8 * data)
-{
-	u8 val;
-	int err;
-
-	err = ec_read(smbus->base + address, &val);
-	if (!err) {
-		*data = val;
-	}
-	xmsleep(ACPI_EC_SMB_TRANSACTION_SLEEP);
-	return (err);
-}
-
-static int acpi_ec_smb_write(struct acpi_ec_smbus *smbus, u8 address, u8 data)
-{
-	int err;
-
-	err = ec_write(smbus->base + address, data);
-	return (err);
-}
-
-static int
-acpi_ec_smb_access(struct i2c_adapter *adap, u16 addr, unsigned short flags,
-		   char read_write, u8 command, int size,
-		   union i2c_smbus_data *data)
-{
-	struct acpi_ec_smbus *smbus = adap->algo_data;
-	unsigned char protocol, len = 0, pec, temp[2] = { 0, 0 };
-	int i;
-
-	if (read_write == I2C_SMBUS_READ) {
-		protocol = ACPI_EC_SMB_PRTCL_READ;
-	} else {
-		protocol = ACPI_EC_SMB_PRTCL_WRITE;
-	}
-	pec = (flags & I2C_CLIENT_PEC) ? ACPI_EC_SMB_PRTCL_PEC : 0;
-
-	switch (size) {
-
-	case I2C_SMBUS_QUICK:
-		protocol |= ACPI_EC_SMB_PRTCL_QUICK;
-		read_write = I2C_SMBUS_WRITE;
-		break;
-
-	case I2C_SMBUS_BYTE:
-		if (read_write == I2C_SMBUS_WRITE) {
-			acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA, data->byte);
-		}
-		protocol |= ACPI_EC_SMB_PRTCL_BYTE;
-		break;
-
-	case I2C_SMBUS_BYTE_DATA:
-		acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command);
-		if (read_write == I2C_SMBUS_WRITE) {
-			acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA, data->byte);
-		}
-		protocol |= ACPI_EC_SMB_PRTCL_BYTE_DATA;
-		break;
-
-	case I2C_SMBUS_WORD_DATA:
-		acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command);
-		if (read_write == I2C_SMBUS_WRITE) {
-			acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA, data->word);
-			acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA + 1,
-					  data->word >> 8);
-		}
-		protocol |= ACPI_EC_SMB_PRTCL_WORD_DATA | pec;
-		break;
-
-	case I2C_SMBUS_BLOCK_DATA:
-		acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command);
-		if (read_write == I2C_SMBUS_WRITE) {
-			len = min_t(u8, data->block[0], 32);
-			acpi_ec_smb_write(smbus, ACPI_EC_SMB_BCNT, len);
-			for (i = 0; i < len; i++)
-				acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA + i,
-						  data->block[i + 1]);
-		}
-		protocol |= ACPI_EC_SMB_PRTCL_BLOCK_DATA | pec;
-		break;
-
-	case I2C_SMBUS_I2C_BLOCK_DATA:
-		len = min_t(u8, data->block[0], 32);
-		acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command);
-		acpi_ec_smb_write(smbus, ACPI_EC_SMB_BCNT, len);
-		if (read_write == I2C_SMBUS_WRITE) {
-			for (i = 0; i < len; i++) {
-				acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA + i,
-						  data->block[i + 1]);
-			}
-		}
-		protocol |= ACPI_EC_SMB_PRTCL_I2C_BLOCK_DATA;
-		break;
-
-	case I2C_SMBUS_PROC_CALL:
-		acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command);
-		acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA, data->word);
-		acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA + 1, data->word >> 8);
-		protocol = ACPI_EC_SMB_PRTCL_PROC_CALL | pec;
-		read_write = I2C_SMBUS_READ;
-		break;
-
-	case I2C_SMBUS_BLOCK_PROC_CALL:
-		protocol |= pec;
-		len = min_t(u8, data->block[0], 31);
-		acpi_ec_smb_write(smbus, ACPI_EC_SMB_CMD, command);
-		acpi_ec_smb_write(smbus, ACPI_EC_SMB_BCNT, len);
-		for (i = 0; i < len; i++)
-			acpi_ec_smb_write(smbus, ACPI_EC_SMB_DATA + i,
-					  data->block[i + 1]);
-		protocol = ACPI_EC_SMB_PRTCL_BLOCK_PROC_CALL | pec;
-		read_write = I2C_SMBUS_READ;
-		break;
-
-	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "EC SMBus adapter: "
-				  "Unsupported transaction %d\n", size));
-		return (-1);
-	}
-
-	acpi_ec_smb_write(smbus, ACPI_EC_SMB_ADDR, addr << 1);
-	acpi_ec_smb_write(smbus, ACPI_EC_SMB_PRTCL, protocol);
-
-	acpi_ec_smb_read(smbus, ACPI_EC_SMB_STS, temp + 0);
-
-	if (~temp[0] & ACPI_EC_SMB_STS_DONE) {
-		xudelay(500);
-		acpi_ec_smb_read(smbus, ACPI_EC_SMB_STS, temp + 0);
-	}
-	if (~temp[0] & ACPI_EC_SMB_STS_DONE) {
-		xmsleep(ACPI_EC_SMB_ACCESS_SLEEP2);
-		acpi_ec_smb_read(smbus, ACPI_EC_SMB_STS, temp + 0);
-	}
-	if ((~temp[0] & ACPI_EC_SMB_STS_DONE)
-	    || (temp[0] & ACPI_EC_SMB_STS_STATUS)) {
-		return (-1);
-	}
-
-	if (read_write == I2C_SMBUS_WRITE) {
-		return (0);
-	}
-
-	switch (size) {
-
-	case I2C_SMBUS_BYTE:
-	case I2C_SMBUS_BYTE_DATA:
-		acpi_ec_smb_read(smbus, ACPI_EC_SMB_DATA, &data->byte);
-		break;
-
-	case I2C_SMBUS_WORD_DATA:
-	case I2C_SMBUS_PROC_CALL:
-		acpi_ec_smb_read(smbus, ACPI_EC_SMB_DATA, temp + 0);
-		acpi_ec_smb_read(smbus, ACPI_EC_SMB_DATA + 1, temp + 1);
-		data->word = (temp[1] << 8) | temp[0];
-		break;
-
-	case I2C_SMBUS_BLOCK_DATA:
-	case I2C_SMBUS_BLOCK_PROC_CALL:
-		len = 0;
-		acpi_ec_smb_read(smbus, ACPI_EC_SMB_BCNT, &len);
-		len = min_t(u8, len, 32);
-	case I2C_SMBUS_I2C_BLOCK_DATA:
-		for (i = 0; i < len; i++)
-			acpi_ec_smb_read(smbus, ACPI_EC_SMB_DATA + i,
-					 data->block + i + 1);
-		data->block[0] = len;
-		break;
-	}
-
-	return (0);
-}
-
-static u32 acpi_ec_smb_func(struct i2c_adapter *adapter)
-{
-
-	return (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
-		I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
-		I2C_FUNC_SMBUS_BLOCK_DATA |
-		I2C_FUNC_SMBUS_PROC_CALL |
-		I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
-		I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_HWPEC_CALC);
-}
-
-static const struct i2c_algorithm acpi_ec_smbus_algorithm = {
-	.smbus_xfer = acpi_ec_smb_access,
-	.functionality = acpi_ec_smb_func,
-};
-
-static int acpi_ec_hc_add(struct acpi_device *device)
-{
-	int status;
-	unsigned long val;
-	struct acpi_ec_hc *ec_hc;
-	struct acpi_ec_smbus *smbus;
-
-	if (!device) {
-		return -EINVAL;
-	}
-
-	ec_hc = kzalloc(sizeof(struct acpi_ec_hc), GFP_KERNEL);
-	if (!ec_hc) {
-		return -ENOMEM;
-	}
-
-	smbus = kzalloc(sizeof(struct acpi_ec_smbus), GFP_KERNEL);
-	if (!smbus) {
-		kfree(ec_hc);
-		return -ENOMEM;
-	}
-
-	ec_hc->handle = device->handle;
-	strcpy(acpi_device_name(device), ACPI_EC_HC_DEVICE_NAME);
-	strcpy(acpi_device_class(device), ACPI_EC_HC_CLASS);
-	acpi_driver_data(device) = ec_hc;
-
-	status = acpi_evaluate_integer(ec_hc->handle, "_EC", NULL, &val);
-	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error obtaining _EC\n"));
-		kfree(ec_hc);
-		kfree(smbus);
-		return -EIO;
-	}
-
-	smbus->ec = acpi_driver_data(device->parent);
-	smbus->base = (val & 0xff00ull) >> 8;
-	smbus->alert = val & 0xffull;
-
-	smbus->adapter.owner = THIS_MODULE;
-	smbus->adapter.algo = &acpi_ec_smbus_algorithm;
-	smbus->adapter.algo_data = smbus;
-	smbus->adapter.dev.parent = &device->dev;
-
-	if (i2c_add_adapter(&smbus->adapter)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN,
-				  "EC SMBus adapter: Failed to register adapter\n"));
-		kfree(smbus);
-		kfree(ec_hc);
-		return -EIO;
-	}
-
-	ec_hc->smbus = smbus;
-
-	printk(KERN_INFO PREFIX "%s [%s]\n",
-	       acpi_device_name(device), acpi_device_bid(device));
-
-	return AE_OK;
-}
-
-static int acpi_ec_hc_remove(struct acpi_device *device, int type)
-{
-	struct acpi_ec_hc *ec_hc;
-
-	if (!device) {
-		return -EINVAL;
-	}
-	ec_hc = acpi_driver_data(device);
-
-	i2c_del_adapter(&ec_hc->smbus->adapter);
-	kfree(ec_hc->smbus);
-	kfree(ec_hc);
-
-	return AE_OK;
-}
-
-static int __init acpi_ec_hc_init(void)
-{
-	int result;
-
-	result = acpi_bus_register_driver(&acpi_ec_hc_driver);
-	if (result < 0) {
-		return -ENODEV;
-	}
-	return 0;
-}
-
-static void __exit acpi_ec_hc_exit(void)
-{
-	acpi_bus_unregister_driver(&acpi_ec_hc_driver);
-}
-
-struct acpi_ec_hc *acpi_get_ec_hc(struct acpi_device *device)
-{
-	return acpi_driver_data(device->parent);
-}
-
-EXPORT_SYMBOL(acpi_get_ec_hc);
-
-module_init(acpi_ec_hc_init);
-module_exit(acpi_ec_hc_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Ducrot Bruno");
-MODULE_DESCRIPTION("ACPI EC SMBus driver");
diff --git a/drivers/acpi/i2c_ec.h b/drivers/acpi/i2c_ec.h
deleted file mode 100644
index 7c53fb7..0000000
--- a/drivers/acpi/i2c_ec.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * SMBus driver for ACPI Embedded Controller ($Revision: 1.2 $)
- *
- * Copyright (c) 2002, 2005 Ducrot Bruno
- *
- * 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.
- */
-
-struct acpi_ec_smbus {
-	struct i2c_adapter adapter;
-	union acpi_ec *ec;
-	int base;
-	int alert;
-};
-
-struct acpi_ec_hc {
-	acpi_handle handle;
-	struct acpi_ec_smbus *smbus;
-};
-
-struct acpi_ec_hc *acpi_get_ec_hc(struct acpi_device *device);
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 024/105] ACPI: ibm-acpi: kill trailing whitespace
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

I shall protect the ibm-acpi city against the invasion of the barbarian
blanks!  To the unforgiving jaws of sed s/[[:blank:]]\+$// they go!

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 Documentation/ibm-acpi.txt |    6 +++---
 drivers/acpi/ibm_acpi.c    |    6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/Documentation/ibm-acpi.txt b/Documentation/ibm-acpi.txt
index 0132d36..cdcef01 100644
--- a/Documentation/ibm-acpi.txt
+++ b/Documentation/ibm-acpi.txt
@@ -21,7 +21,7 @@ detailed description):
 
 	- Fn key combinations
 	- Bluetooth enable and disable
-	- video output switching, expansion control	
+	- video output switching, expansion control
 	- ThinkLight on and off
 	- limited docking and undocking
 	- UltraBay eject
@@ -472,7 +472,7 @@ This feature dumps the values of 256 embedded controller
 registers. Values which have changed since the last time the registers
 were dumped are marked with a star:
 
-[root@x40 ibm-acpi]# cat /proc/acpi/ibm/ecdump 
+[root@x40 ibm-acpi]# cat /proc/acpi/ibm/ecdump
 EC       +00 +01 +02 +03 +04 +05 +06 +07 +08 +09 +0a +0b +0c +0d +0e +0f
 EC 0x00:  a7  47  87  01  fe  96  00  08  01  00  cb  00  00  00  40  00
 EC 0x10:  00  00  ff  ff  f4  3c  87  09  01  ff  42  01  ff  ff  0d  00
@@ -503,7 +503,7 @@ vary. The second ensures that the fan-related values do vary, since
 the fan speed fluctuates a bit. The third will (hopefully) mark the
 fan register with a star:
 
-[root@x40 ibm-acpi]# cat /proc/acpi/ibm/ecdump 
+[root@x40 ibm-acpi]# cat /proc/acpi/ibm/ecdump
 EC       +00 +01 +02 +03 +04 +05 +06 +07 +08 +09 +0a +0b +0c +0d +0e +0f
 EC 0x00:  a7  47  87  01  fe  96  00  08  01  00  cb  00  00  00  40  00
 EC 0x10:  00  00  ff  ff  f4  3c  87  09  01  ff  42  01  ff  ff  0d  00
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index dc10966..60aaed9 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -28,7 +28,7 @@
  *  2006-11-22	0.13	new maintainer
  *  			changelog now lives in git commit history, and will
  *  			not be updated further in-file.
- *  
+ *
  *  2005-08-17  0.12	fix compilation on 2.6.13-rc kernels
  *  2005-03-17	0.11	support for 600e, 770x
  *			    thanks to Jamie Lentin <lentinj@dial.pipex.com>
@@ -38,7 +38,7 @@
  *			experimental brightness control
  *			experimental volume control
  *			experimental fan enable/disable
- *  2005-01-16	0.10	fix module loading on R30, R31 
+ *  2005-01-16	0.10	fix module loading on R30, R31
  *  2005-01-16	0.9	support for 570, R30, R31
  *			ultrabay support on A22p, A3x
  *			limit arg for cmos, led, beep, drop experimental status
@@ -161,7 +161,7 @@ IBM_HANDLE(dock, root, "\\_SB.GDCK",	/* X30, X31, X40 */
 #ifdef CONFIG_ACPI_IBM_BAY
 IBM_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST",	/* 570 */
 	   "\\_SB.PCI0.IDE0.IDES.IDSM",	/* 600e/x, 770e, 770x */
-	   "\\_SB.PCI0.SATA.SCND.MSTR",	/* T60, X60, Z60 */ 
+	   "\\_SB.PCI0.SATA.SCND.MSTR",	/* T60, X60, Z60 */
 	   "\\_SB.PCI0.IDE0.SCND.MSTR",	/* all others */
     );				/* A21e, R30, R31 */
 
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 025/105] ACPI: ibm-acpi: rename some identifiers
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Rename some identifiers so that they are more in tune with the rest of the
driver code, or less generic.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/ibm_acpi.c |   43 ++++++++++++++++++++++++-------------------
 1 files changed, 24 insertions(+), 19 deletions(-)

diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 60aaed9..41c46b0 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -506,7 +506,7 @@ static int ibm_acpi_driver_init(void)
 	return 0;
 }
 
-static int driver_read(char *p)
+static int ibm_acpi_driver_read(char *p)
 {
 	int len = 0;
 
@@ -1310,9 +1310,9 @@ static const int led_exp_hlbl[] = { 0, 0, 1 };	/* led# * */
 static const int led_exp_hlcl[] = { 0, 1, 1 };	/* led# * */
 static const int led_led_arg1[] = { 0, 0x80, 0xc0 };
 
-#define EC_HLCL 0x0c
-#define EC_HLBL 0x0d
-#define EC_HLMS 0x0e
+#define IBMACPI_LED_EC_HLCL 0x0c
+#define IBMACPI_LED_EC_HLBL 0x0d
+#define IBMACPI_LED_EC_HLMS 0x0e
 
 static int led_write(char *buf)
 {
@@ -1344,13 +1344,15 @@ static int led_write(char *buf)
 		} else if (led_supported == IBMACPI_LED_OLD) {
 			/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
 			led = 1 << led;
-			ret = ec_write(EC_HLMS, led);
+			ret = ec_write(IBMACPI_LED_EC_HLMS, led);
 			if (ret >= 0)
 				ret =
-				    ec_write(EC_HLBL, led * led_exp_hlbl[ind]);
+				    ec_write(IBMACPI_LED_EC_HLBL,
+				    	     led * led_exp_hlbl[ind]);
 			if (ret >= 0)
 				ret =
-				    ec_write(EC_HLCL, led * led_exp_hlcl[ind]);
+				    ec_write(IBMACPI_LED_EC_HLCL,
+				    	     led * led_exp_hlcl[ind]);
 			if (ret < 0)
 				return ret;
 		} else {
@@ -1657,8 +1659,8 @@ static int brightness_read(char *p)
 	return len;
 }
 
-#define BRIGHTNESS_UP	4
-#define BRIGHTNESS_DOWN	5
+#define TP_CMOS_BRIGHTNESS_UP	4
+#define TP_CMOS_BRIGHTNESS_DOWN	5
 
 static int brightness_set(int value)
 {
@@ -1667,7 +1669,8 @@ static int brightness_set(int value)
 
 	value &= 7;
 
-	cmos_cmd = value > current_value ? BRIGHTNESS_UP : BRIGHTNESS_DOWN;
+	cmos_cmd = value > current_value ?
+		   TP_CMOS_BRIGHTNESS_UP : TP_CMOS_BRIGHTNESS_DOWN;
 	inc = value > current_value ? 1 : -1;
 	for (i = current_value; i != value; i += inc) {
 		if (!cmos_eval(cmos_cmd))
@@ -1769,9 +1772,9 @@ static int volume_read(char *p)
 	return len;
 }
 
-#define VOLUME_DOWN	0
-#define VOLUME_UP	1
-#define VOLUME_MUTE	2
+#define TP_CMOS_VOLUME_DOWN	0
+#define TP_CMOS_VOLUME_UP	1
+#define TP_CMOS_VOLUME_MUTE	2
 
 static int volume_write(char *buf)
 {
@@ -1805,7 +1808,8 @@ static int volume_write(char *buf)
 			return -EINVAL;
 
 		if (new_level != level) {	/* mute doesn't change */
-			cmos_cmd = new_level > level ? VOLUME_UP : VOLUME_DOWN;
+			cmos_cmd = new_level > level ?
+					TP_CMOS_VOLUME_UP : TP_CMOS_VOLUME_DOWN;
 			inc = new_level > level ? 1 : -1;
 
 			if (mute && (!cmos_eval(cmos_cmd) ||
@@ -1817,14 +1821,15 @@ static int volume_write(char *buf)
 				    !acpi_ec_write(volume_offset, i + inc))
 					return -EIO;
 
-			if (mute && (!cmos_eval(VOLUME_MUTE) ||
+			if (mute && (!cmos_eval(TP_CMOS_VOLUME_MUTE) ||
 				     !acpi_ec_write(volume_offset,
 						    new_level + mute)))
 				return -EIO;
 		}
 
 		if (new_mute != mute) {	/* level doesn't change */
-			cmos_cmd = new_mute ? VOLUME_MUTE : VOLUME_UP;
+			cmos_cmd = new_mute ?
+				   TP_CMOS_VOLUME_MUTE : TP_CMOS_VOLUME_UP;
 
 			if (!cmos_eval(cmos_cmd) ||
 			    !acpi_ec_write(volume_offset, level + new_mute))
@@ -2315,7 +2320,7 @@ static struct ibm_struct ibms[] = {
 	{
 	 .name = "driver",
 	 .init = ibm_acpi_driver_init,
-	 .read = driver_read,
+	 .read = ibm_acpi_driver_read,
 	 },
 	{
 	 .name = "hotkey",
@@ -2534,7 +2539,7 @@ static int __init ibm_device_add(struct acpi_device *device)
 	return 0;
 }
 
-static int __init register_driver(struct ibm_struct *ibm)
+static int __init register_ibmacpi_subdriver(struct ibm_struct *ibm)
 {
 	int ret;
 
@@ -2569,7 +2574,7 @@ static int __init ibm_init(struct ibm_struct *ibm)
 		return 0;
 
 	if (ibm->hid) {
-		ret = register_driver(ibm);
+		ret = register_ibmacpi_subdriver(ibm);
 		if (ret < 0)
 			return ret;
 		ibm->driver_registered = 1;
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 026/105] ACPI: ibm-acpi: add header file
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Add a (private) header file for ibm-acpi, and move type definitions and
ThinkPad driver constants to the new header file.

This patch has no functional changes.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/ibm_acpi.c |  139 +---------------
 drivers/acpi/ibm_acpi.h |  437 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 438 insertions(+), 138 deletions(-)
 create mode 100644 drivers/acpi/ibm_acpi.h

diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 41c46b0..e2da954 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -78,44 +78,13 @@
  *  2004-08-09	0.1	initial release, support for X series
  */
 
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/string.h>
-
-#include <linux/proc_fs.h>
-#include <linux/backlight.h>
-#include <linux/fb.h>
-#include <asm/uaccess.h>
-
-#include <linux/dmi.h>
-#include <linux/jiffies.h>
-#include <linux/workqueue.h>
-
-#include <acpi/acpi_drivers.h>
-#include <acpi/acnamesp.h>
-
-#define IBM_NAME "ibm"
-#define IBM_DESC "IBM ThinkPad ACPI Extras"
-#define IBM_FILE "ibm_acpi"
-#define IBM_URL "http://ibm-acpi.sf.net/"
+#include "ibm_acpi.h"
 
 MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh");
 MODULE_DESCRIPTION(IBM_DESC);
 MODULE_VERSION(IBM_VERSION);
 MODULE_LICENSE("GPL");
 
-#define IBM_DIR IBM_NAME
-
-#define IBM_LOG IBM_FILE ": "
-#define IBM_ERR	   KERN_ERR    IBM_LOG
-#define IBM_NOTICE KERN_NOTICE IBM_LOG
-#define IBM_INFO   KERN_INFO   IBM_LOG
-#define IBM_DEBUG  KERN_DEBUG  IBM_LOG
-
-#define IBM_MAX_ACPI_ARGS 3
-
 #define __unused __attribute__ ((unused))
 
 static int experimental;
@@ -207,22 +176,6 @@ IBM_HANDLE(sfan, ec, "SFAN",	/* 570 */
 	   "JFNS",		/* 770x-JL */
     );				/* all others */
 
-#define IBM_HKEY_HID	"IBM0068"
-#define IBM_PCI_HID	"PNP0A03"
-
-enum thermal_access_mode {
-	IBMACPI_THERMAL_NONE = 0,	/* No thermal support */
-	IBMACPI_THERMAL_ACPI_TMP07,	/* Use ACPI TMP0-7 */
-	IBMACPI_THERMAL_ACPI_UPDT,	/* Use ACPI TMP0-7 with UPDT */
-	IBMACPI_THERMAL_TPEC_8,		/* Use ACPI EC regs, 8 sensors */
-	IBMACPI_THERMAL_TPEC_16,	/* Use ACPI EC regs, 16 sensors */
-};
-
-#define IBMACPI_MAX_THERMAL_SENSORS 16	/* Max thermal sensors supported */
-struct ibm_thermal_sensors_struct {
-	s32 temp[IBMACPI_MAX_THERMAL_SENSORS];
-};
-
 /*
  * FAN ACCESS MODES
  *
@@ -323,72 +276,12 @@ struct ibm_thermal_sensors_struct {
  * 	but the ACPI tables just mention level 7.
  */
 
-enum fan_status_access_mode {
-	IBMACPI_FAN_NONE = 0,		/* No fan status or control */
-	IBMACPI_FAN_RD_ACPI_GFAN,	/* Use ACPI GFAN */
-	IBMACPI_FAN_RD_TPEC,		/* Use ACPI EC regs 0x2f, 0x84-0x85 */
-};
-
-enum fan_control_access_mode {
-	IBMACPI_FAN_WR_NONE = 0,	/* No fan control */
-	IBMACPI_FAN_WR_ACPI_SFAN,	/* Use ACPI SFAN */
-	IBMACPI_FAN_WR_TPEC,		/* Use ACPI EC reg 0x2f */
-	IBMACPI_FAN_WR_ACPI_FANS,	/* Use ACPI FANS and EC reg 0x2f */
-};
-
-enum fan_control_commands {
-	IBMACPI_FAN_CMD_SPEED 	= 0x0001,	/* speed command */
-	IBMACPI_FAN_CMD_LEVEL 	= 0x0002,	/* level command  */
-	IBMACPI_FAN_CMD_ENABLE	= 0x0004,	/* enable/disable cmd,
-						 * and also watchdog cmd */
-};
-
-enum {					/* Fan control constants */
-	fan_status_offset = 0x2f,	/* EC register 0x2f */
-	fan_rpm_offset = 0x84,		/* EC register 0x84: LSB, 0x85 MSB (RPM)
-					 * 0x84 must be read before 0x85 */
-
-	IBMACPI_FAN_EC_DISENGAGED 	= 0x40,	/* EC mode: tachometer
-						 * disengaged */
-	IBMACPI_FAN_EC_AUTO		= 0x80, /* EC mode: auto fan
-						 * control */
-};
-
 static char *ibm_thinkpad_ec_found = NULL;
 
-struct ibm_struct {
-	char *name;
-	char param[32];
-
-	char *hid;
-	struct acpi_driver *driver;
-
-	int (*init) (void);
-	int (*read) (char *);
-	int (*write) (char *);
-	void (*exit) (void);
-
-	void (*notify) (struct ibm_struct *, u32);
-	acpi_handle *handle;
-	int type;
-	struct acpi_device *device;
-
-	int driver_registered;
-	int proc_created;
-	int init_called;
-	int notify_installed;
-
-	int experimental;
-};
-
 static struct proc_dir_entry *proc_dir = NULL;
 
 static struct backlight_device *ibm_backlight_device = NULL;
 
-#define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off")
-#define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
-#define strlencmp(a,b) (strncmp((a), (b), strlen(b)))
-
 static int acpi_evalf(acpi_handle handle,
 		      void *res, char *method, char *fmt, ...)
 {
@@ -775,13 +668,6 @@ static int wan_write(char *buf)
 	return 0;
 }
 
-enum video_access_mode {
-	IBMACPI_VIDEO_NONE = 0,
-	IBMACPI_VIDEO_570,	/* 570 */
-	IBMACPI_VIDEO_770,	/* 600e/x, 770e, 770x */
-	IBMACPI_VIDEO_NEW,	/* all others */
-};
-
 static enum video_access_mode video_supported;
 static int video_orig_autosw;
 
@@ -1248,12 +1134,6 @@ static int cmos_write(char *buf)
 	return 0;
 }
 
-enum led_access_mode {
-	IBMACPI_LED_NONE = 0,
-	IBMACPI_LED_570,	/* 570 */
-	IBMACPI_LED_OLD,	/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
-	IBMACPI_LED_NEW,	/* all others */
-};
 static enum led_access_mode led_supported;
 
 static int led_init(void)
@@ -1310,10 +1190,6 @@ static const int led_exp_hlbl[] = { 0, 0, 1 };	/* led# * */
 static const int led_exp_hlcl[] = { 0, 1, 1 };	/* led# * */
 static const int led_led_arg1[] = { 0, 0x80, 0xc0 };
 
-#define IBMACPI_LED_EC_HLCL 0x0c
-#define IBMACPI_LED_EC_HLBL 0x0d
-#define IBMACPI_LED_EC_HLMS 0x0e
-
 static int led_write(char *buf)
 {
 	char *cmd;
@@ -1629,8 +1505,6 @@ static int ecdump_write(char *buf)
 	return 0;
 }
 
-static int brightness_offset = 0x31;
-
 static int brightness_get(struct backlight_device *bd)
 {
 	u8 level;
@@ -1659,9 +1533,6 @@ static int brightness_read(char *p)
 	return len;
 }
 
-#define TP_CMOS_BRIGHTNESS_UP	4
-#define TP_CMOS_BRIGHTNESS_DOWN	5
-
 static int brightness_set(int value)
 {
 	int cmos_cmd, inc, i;
@@ -1752,8 +1623,6 @@ static void brightness_exit(void)
 	}
 }
 
-static int volume_offset = 0x30;
-
 static int volume_read(char *p)
 {
 	int len = 0;
@@ -1772,10 +1641,6 @@ static int volume_read(char *p)
 	return len;
 }
 
-#define TP_CMOS_VOLUME_DOWN	0
-#define TP_CMOS_VOLUME_UP	1
-#define TP_CMOS_VOLUME_MUTE	2
-
 static int volume_write(char *buf)
 {
 	int cmos_cmd, inc, i;
@@ -2563,8 +2428,6 @@ static int __init register_ibmacpi_subdriver(struct ibm_struct *ibm)
 	return ret;
 }
 
-static void ibm_exit(struct ibm_struct *ibm);
-
 static int __init ibm_init(struct ibm_struct *ibm)
 {
 	int ret;
diff --git a/drivers/acpi/ibm_acpi.h b/drivers/acpi/ibm_acpi.h
new file mode 100644
index 0000000..7ebaaa4
--- /dev/null
+++ b/drivers/acpi/ibm_acpi.h
@@ -0,0 +1,437 @@
+/*
+ *  ibm_acpi.h - IBM ThinkPad ACPI Extras
+ *
+ *
+ *  Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>
+ *  Copyright (C) 2006-2007 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+ *
+ *  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; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ *  02110-1301, USA.
+ */
+
+#ifndef __IBM_ACPI_H__
+#define __IBM_ACPI_H__
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/string.h>
+
+#include <linux/proc_fs.h>
+#include <linux/backlight.h>
+#include <linux/fb.h>
+#include <asm/uaccess.h>
+
+#include <linux/dmi.h>
+#include <linux/jiffies.h>
+#include <linux/workqueue.h>
+
+#include <acpi/acpi_drivers.h>
+#include <acpi/acnamesp.h>
+
+
+/****************************************************************************
+ * Main driver
+ */
+
+#define IBM_NAME "ibm"
+#define IBM_DESC "IBM ThinkPad ACPI Extras"
+#define IBM_FILE "ibm_acpi"
+#define IBM_URL "http://ibm-acpi.sf.net/"
+
+#define IBM_DIR IBM_NAME
+
+#define IBM_LOG IBM_FILE ": "
+#define IBM_ERR	   KERN_ERR    IBM_LOG
+#define IBM_NOTICE KERN_NOTICE IBM_LOG
+#define IBM_INFO   KERN_INFO   IBM_LOG
+#define IBM_DEBUG  KERN_DEBUG  IBM_LOG
+
+#define IBM_MAX_ACPI_ARGS 3
+
+/* ThinkPad CMOS commands */
+#define TP_CMOS_VOLUME_DOWN	0
+#define TP_CMOS_VOLUME_UP	1
+#define TP_CMOS_VOLUME_MUTE	2
+#define TP_CMOS_BRIGHTNESS_UP	4
+#define TP_CMOS_BRIGHTNESS_DOWN	5
+
+#define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off")
+#define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
+#define strlencmp(a,b) (strncmp((a), (b), strlen(b)))
+
+/* ACPI HIDs */
+#define IBM_HKEY_HID    "IBM0068"
+#define IBM_PCI_HID     "PNP0A03"
+
+/* ACPI helpers */
+static int acpi_evalf(acpi_handle handle,
+		      void *res, char *method, char *fmt, ...);
+static int acpi_ec_read(int i, u8 * p);
+static int acpi_ec_write(int i, u8 v);
+static int _sta(acpi_handle handle);
+
+/* ACPI handles */
+static acpi_handle root_handle;			/* root namespace */
+static acpi_handle ec_handle;			/* EC */
+static acpi_handle ecrd_handle, ecwr_handle;	/* 570 EC access */
+static acpi_handle cmos_handle, hkey_handle;	/* basic thinkpad handles */
+
+static void ibm_handle_init(char *name,
+		   acpi_handle * handle, acpi_handle parent,
+		   char **paths, int num_paths, char **path);
+#define IBM_HANDLE_INIT(object)						\
+	ibm_handle_init(#object, &object##_handle, *object##_parent,	\
+		object##_paths, ARRAY_SIZE(object##_paths), &object##_path)
+
+/* procfs support */
+static struct proc_dir_entry *proc_dir;
+static int ibm_acpi_driver_init(void);
+static int ibm_acpi_driver_read(char *p);
+
+/* procfs helpers */
+static int dispatch_read(char *page, char **start, off_t off, int count,
+		int *eof, void *data);
+static int dispatch_write(struct file *file, const char __user * userbuf,
+		unsigned long count, void *data);
+static char *next_cmd(char **cmds);
+
+/* Module */
+static int experimental;
+static char *ibm_thinkpad_ec_found;
+
+static char* check_dmi_for_ec(void);
+static int acpi_ibm_init(void);
+static void acpi_ibm_exit(void);
+
+
+/****************************************************************************
+ * Subdrivers
+ */
+
+struct ibm_struct {
+	char *name;
+	char param[32];
+
+	char *hid;
+	struct acpi_driver *driver;
+
+	int (*init) (void);
+	int (*read) (char *);
+	int (*write) (char *);
+	void (*exit) (void);
+
+	void (*notify) (struct ibm_struct *, u32);
+	acpi_handle *handle;
+	int type;
+	struct acpi_device *device;
+
+	int driver_registered;
+	int proc_created;
+	int init_called;
+	int notify_installed;
+
+	int experimental;
+};
+
+static struct ibm_struct ibms[];
+static int set_ibm_param(const char *val, struct kernel_param *kp);
+static int ibm_init(struct ibm_struct *ibm);
+static void ibm_exit(struct ibm_struct *ibm);
+
+/* ACPI devices */
+static void dispatch_notify(acpi_handle handle, u32 event, void *data);
+static int setup_notify(struct ibm_struct *ibm);
+static int ibm_device_add(struct acpi_device *device);
+static int register_ibmacpi_subdriver(struct ibm_struct *ibm);
+
+
+/*
+ * Bay subdriver
+ */
+
+#ifdef CONFIG_ACPI_IBM_BAY
+static int bay_status_supported, bay_eject_supported;
+static int bay_status2_supported, bay_eject2_supported;
+
+static acpi_handle bay_handle, bay_ej_handle;
+static acpi_handle bay2_handle, bay2_ej_handle;
+
+static int bay_init(void);
+static void bay_notify(struct ibm_struct *ibm, u32 event);
+static int bay_read(char *p);
+static int bay_write(char *buf);
+#endif /* CONFIG_ACPI_IBM_BAY */
+
+
+/*
+ * Beep subdriver
+ */
+
+static acpi_handle beep_handle;
+
+static int beep_read(char *p);
+static int beep_write(char *buf);
+
+
+/*
+ * Bluetooth subdriver
+ */
+
+static int bluetooth_supported;
+
+static int bluetooth_init(void);
+static int bluetooth_status(void);
+static int bluetooth_read(char *p);
+static int bluetooth_write(char *buf);
+
+
+/*
+ * Brightness (backlight) subdriver
+ */
+
+static struct backlight_device *ibm_backlight_device;
+static int brightness_offset = 0x31;
+
+static int brightness_init(void);
+static void brightness_exit(void);
+static int brightness_get(struct backlight_device *bd);
+static int brightness_set(int value);
+static int brightness_update_status(struct backlight_device *bd);
+static int brightness_read(char *p);
+static int brightness_write(char *buf);
+
+
+/*
+ * CMOS subdriver
+ */
+
+static int cmos_eval(int cmos_cmd);
+static int cmos_read(char *p);
+static int cmos_write(char *buf);
+
+
+/*
+ * Dock subdriver
+ */
+
+static acpi_handle pci_handle;
+#ifdef CONFIG_ACPI_IBM_DOCK
+static acpi_handle dock_handle;
+
+static void dock_notify(struct ibm_struct *ibm, u32 event);
+static int dock_read(char *p);
+static int dock_write(char *buf);
+#endif /* CONFIG_ACPI_IBM_DOCK */
+
+
+/*
+ * EC dump subdriver
+ */
+
+static int ecdump_read(char *p) ;
+static int ecdump_write(char *buf);
+
+
+/*
+ * Fan subdriver
+ */
+
+enum {					/* Fan control constants */
+	fan_status_offset = 0x2f,	/* EC register 0x2f */
+	fan_rpm_offset = 0x84,		/* EC register 0x84: LSB, 0x85 MSB (RPM)
+					 * 0x84 must be read before 0x85 */
+
+	IBMACPI_FAN_EC_DISENGAGED 	= 0x40,	/* EC mode: tachometer
+						 * disengaged */
+	IBMACPI_FAN_EC_AUTO		= 0x80, /* EC mode: auto fan
+						 * control */
+};
+
+enum fan_status_access_mode {
+	IBMACPI_FAN_NONE = 0,		/* No fan status or control */
+	IBMACPI_FAN_RD_ACPI_GFAN,	/* Use ACPI GFAN */
+	IBMACPI_FAN_RD_TPEC,		/* Use ACPI EC regs 0x2f, 0x84-0x85 */
+};
+
+enum fan_control_access_mode {
+	IBMACPI_FAN_WR_NONE = 0,	/* No fan control */
+	IBMACPI_FAN_WR_ACPI_SFAN,	/* Use ACPI SFAN */
+	IBMACPI_FAN_WR_TPEC,		/* Use ACPI EC reg 0x2f */
+	IBMACPI_FAN_WR_ACPI_FANS,	/* Use ACPI FANS and EC reg 0x2f */
+};
+
+enum fan_control_commands {
+	IBMACPI_FAN_CMD_SPEED 	= 0x0001,	/* speed command */
+	IBMACPI_FAN_CMD_LEVEL 	= 0x0002,	/* level command  */
+	IBMACPI_FAN_CMD_ENABLE	= 0x0004,	/* enable/disable cmd,
+						 * and also watchdog cmd */
+};
+
+static enum fan_status_access_mode fan_status_access_mode;
+static enum fan_control_access_mode fan_control_access_mode;
+static enum fan_control_commands fan_control_commands;
+static int fan_control_status_known;
+static u8 fan_control_initial_status;
+static int fan_watchdog_maxinterval;
+
+static acpi_handle fans_handle, gfan_handle, sfan_handle;
+
+static int fan_init(void);
+static void fan_exit(void);
+static int fan_get_status(u8 *status);
+static int fan_get_speed(unsigned int *speed);
+static void fan_watchdog_fire(struct work_struct *ignored);
+static void fan_watchdog_reset(void);
+static int fan_set_level(int level);
+static int fan_set_enable(void);
+static int fan_set_disable(void);
+static int fan_set_speed(int speed);
+static int fan_read(char *p);
+static int fan_write(char *buf);
+static int fan_write_cmd_level(const char *cmd, int *rc);
+static int fan_write_cmd_enable(const char *cmd, int *rc);
+static int fan_write_cmd_disable(const char *cmd, int *rc);
+static int fan_write_cmd_speed(const char *cmd, int *rc);
+static int fan_write_cmd_watchdog(const char *cmd, int *rc);
+
+
+/*
+ * Hotkey subdriver
+ */
+
+static int hotkey_supported;
+static int hotkey_mask_supported;
+static int hotkey_orig_status;
+static int hotkey_orig_mask;
+
+static int hotkey_init(void);
+static void hotkey_exit(void);
+static int hotkey_get(int *status, int *mask);
+static int hotkey_set(int status, int mask);
+static void hotkey_notify(struct ibm_struct *ibm, u32 event);
+static int hotkey_read(char *p);
+static int hotkey_write(char *buf);
+
+
+/*
+ * LED subdriver
+ */
+
+enum led_access_mode {
+	IBMACPI_LED_NONE = 0,
+	IBMACPI_LED_570,	/* 570 */
+	IBMACPI_LED_OLD,	/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
+	IBMACPI_LED_NEW,	/* all others */
+};
+
+enum {	/* For IBMACPI_LED_OLD */
+	IBMACPI_LED_EC_HLCL = 0x0c,	/* EC reg to get led to power on */
+	IBMACPI_LED_EC_HLBL = 0x0d,	/* EC reg to blink a lit led */
+	IBMACPI_LED_EC_HLMS = 0x0e,	/* EC reg to select led to command */
+};
+
+static enum led_access_mode led_supported;
+static acpi_handle led_handle;
+
+static int led_init(void);
+static int led_read(char *p);
+static int led_write(char *buf);
+
+/*
+ * Light (thinklight) subdriver
+ */
+
+static int light_supported;
+static int light_status_supported;
+static acpi_handle lght_handle, ledb_handle;
+
+static int light_init(void);
+static int light_read(char *p);
+static int light_write(char *buf);
+
+
+/*
+ * Thermal subdriver
+ */
+
+enum thermal_access_mode {
+	IBMACPI_THERMAL_NONE = 0,	/* No thermal support */
+	IBMACPI_THERMAL_ACPI_TMP07,	/* Use ACPI TMP0-7 */
+	IBMACPI_THERMAL_ACPI_UPDT,	/* Use ACPI TMP0-7 with UPDT */
+	IBMACPI_THERMAL_TPEC_8,		/* Use ACPI EC regs, 8 sensors */
+	IBMACPI_THERMAL_TPEC_16,	/* Use ACPI EC regs, 16 sensors */
+};
+
+#define IBMACPI_MAX_THERMAL_SENSORS 16	/* Max thermal sensors supported */
+struct ibm_thermal_sensors_struct {
+	s32 temp[IBMACPI_MAX_THERMAL_SENSORS];
+};
+
+static int thermal_init(void);
+static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s);
+static int thermal_read(char *p);
+
+
+/*
+ * Video subdriver
+ */
+
+enum video_access_mode {
+	IBMACPI_VIDEO_NONE = 0,
+	IBMACPI_VIDEO_570,	/* 570 */
+	IBMACPI_VIDEO_770,	/* 600e/x, 770e, 770x */
+	IBMACPI_VIDEO_NEW,	/* all others */
+};
+
+static enum video_access_mode video_supported;
+static int video_orig_autosw;
+static acpi_handle vid_handle, vid2_handle;
+
+static int video_init(void);
+static void video_exit(void);
+static int video_status(void);
+static int video_autosw(void);
+static int video_switch(void);
+static int video_switch2(int status);
+static int video_expand(void);
+static int video_read(char *p);
+static int video_write(char *buf);
+
+
+/*
+ * Volume subdriver
+ */
+
+static int volume_offset = 0x30;
+
+static int volume_read(char *p);
+static int volume_write(char *buf);
+
+
+/*
+ * Wan subdriver
+ */
+
+static int wan_supported;
+
+static int wan_init(void);
+static int wan_status(void);
+static int wan_read(char *p);
+static int wan_write(char *buf);
+
+
+#endif /* __IBM_ACPI_H */
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 027/105] ACPI: ibm-acpi: organize code
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Shuffle code around to better organize the driver code inside the
ibm-acpi.c file.

This patch adds no functional changes.  It is pure fluff that will make me
a bit more productive.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/ibm_acpi.c | 1398 +++++++++++++++++++++++++----------------------
 1 files changed, 757 insertions(+), 641 deletions(-)

diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index e2da954..984ec81 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -87,8 +87,17 @@ MODULE_LICENSE("GPL");
 
 #define __unused __attribute__ ((unused))
 
-static int experimental;
-module_param(experimental, int, 0);
+/****************************************************************************
+ ****************************************************************************
+ *
+ * ACPI Helpers and device model
+ *
+ ****************************************************************************
+ ****************************************************************************/
+
+/*************************************************************************
+ * ACPI basic handles
+ */
 
 static acpi_handle root_handle = NULL;
 
@@ -105,183 +114,31 @@ IBM_HANDLE(ec, root, "\\_SB.PCI0.ISA.EC0",	/* 240, 240x */
 	   "\\_SB.PCI0.AD4S.EC0",	/* i1400, R30 */
 	   "\\_SB.PCI0.ICH3.EC0",	/* R31 */
 	   "\\_SB.PCI0.LPC.EC",	/* all others */
-    );
+	   );
 
-IBM_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA",	/* 570 */
-	   "\\_SB.PCI0.AGP0.VID0",	/* 600e/x, 770x */
-	   "\\_SB.PCI0.VID0",	/* 770e */
-	   "\\_SB.PCI0.VID",	/* A21e, G4x, R50e, X30, X40 */
-	   "\\_SB.PCI0.AGP.VID",	/* all others */
-    );				/* R30, R31 */
+IBM_HANDLE(ecrd, ec, "ECRD");	/* 570 */
+IBM_HANDLE(ecwr, ec, "ECWR");	/* 570 */
 
-IBM_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID");	/* G41 */
+
+/*************************************************************************
+ * Misc ACPI handles
+ */
 
 IBM_HANDLE(cmos, root, "\\UCMS",	/* R50, R50e, R50p, R51, T4x, X31, X40 */
 	   "\\CMOS",		/* A3x, G4x, R32, T23, T30, X22-24, X30 */
 	   "\\CMS",		/* R40, R40e */
-    );				/* all others */
-#ifdef CONFIG_ACPI_IBM_DOCK
-IBM_HANDLE(dock, root, "\\_SB.GDCK",	/* X30, X31, X40 */
-	   "\\_SB.PCI0.DOCK",	/* 600e/x,770e,770x,A2xm/p,T20-22,X20-21 */
-	   "\\_SB.PCI0.PCI1.DOCK",	/* all others */
-	   "\\_SB.PCI.ISA.SLCE",	/* 570 */
-    );				/* A21e,G4x,R30,R31,R32,R40,R40e,R50e */
-#endif
-#ifdef CONFIG_ACPI_IBM_BAY
-IBM_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST",	/* 570 */
-	   "\\_SB.PCI0.IDE0.IDES.IDSM",	/* 600e/x, 770e, 770x */
-	   "\\_SB.PCI0.SATA.SCND.MSTR",	/* T60, X60, Z60 */
-	   "\\_SB.PCI0.IDE0.SCND.MSTR",	/* all others */
-    );				/* A21e, R30, R31 */
-
-IBM_HANDLE(bay_ej, bay, "_EJ3",	/* 600e/x, A2xm/p, A3x */
-	   "_EJ0",		/* all others */
-    );				/* 570,A21e,G4x,R30,R31,R32,R40e,R50e */
-
-IBM_HANDLE(bay2, root, "\\_SB.PCI0.IDE0.PRIM.SLAV",	/* A3x, R32 */
-	   "\\_SB.PCI0.IDE0.IDEP.IDPS",	/* 600e/x, 770e, 770x */
-    );				/* all others */
-
-IBM_HANDLE(bay2_ej, bay2, "_EJ3",	/* 600e/x, 770e, A3x */
-	   "_EJ0",		/* 770x */
-    );				/* all others */
-#endif /* CONFIG_ACPI_IBM_BAY */
-
-/* don't list other alternatives as we install a notify handler on the 570 */
-IBM_HANDLE(pci, root, "\\_SB.PCI");	/* 570 */
+	   );			/* all others */
 
 IBM_HANDLE(hkey, ec, "\\_SB.HKEY",	/* 600e/x, 770e, 770x */
 	   "^HKEY",		/* R30, R31 */
 	   "HKEY",		/* all others */
-    );				/* 570 */
+	   );			/* 570 */
 
-IBM_HANDLE(lght, root, "\\LGHT");	/* A21e, A2xm/p, T20-22, X20-21 */
-IBM_HANDLE(ledb, ec, "LEDB");	/* G4x */
 
-IBM_HANDLE(led, ec, "SLED",	/* 570 */
-	   "SYSL",		/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
-	   "LED",		/* all others */
-    );				/* R30, R31 */
-
-IBM_HANDLE(beep, ec, "BEEP");	/* all except R30, R31 */
-IBM_HANDLE(ecrd, ec, "ECRD");	/* 570 */
-IBM_HANDLE(ecwr, ec, "ECWR");	/* 570 */
-IBM_HANDLE(fans, ec, "FANS");	/* X31, X40, X41 */
-
-IBM_HANDLE(gfan, ec, "GFAN",	/* 570 */
-	   "\\FSPD",		/* 600e/x, 770e, 770x */
-    );				/* all others */
-
-IBM_HANDLE(sfan, ec, "SFAN",	/* 570 */
-	   "JFNS",		/* 770x-JL */
-    );				/* all others */
-
-/*
- * FAN ACCESS MODES
- *
- * IBMACPI_FAN_RD_ACPI_GFAN:
- * 	ACPI GFAN method: returns fan level
- *
- * 	see IBMACPI_FAN_WR_ACPI_SFAN
- * 	EC 0x2f not available if GFAN exists
- *
- * IBMACPI_FAN_WR_ACPI_SFAN:
- * 	ACPI SFAN method: sets fan level, 0 (stop) to 7 (max)
- *
- * 	EC 0x2f might be available *for reading*, but never for writing.
- *
- * IBMACPI_FAN_WR_TPEC:
- * 	ThinkPad EC register 0x2f (HFSP): fan control loop mode Supported
- * 	on almost all ThinkPads
- *
- * 	Fan speed changes of any sort (including those caused by the
- * 	disengaged mode) are usually done slowly by the firmware as the
- * 	maximum ammount of fan duty cycle change per second seems to be
- * 	limited.
- *
- * 	Reading is not available if GFAN exists.
- * 	Writing is not available if SFAN exists.
- *
- * 	Bits
- *	 7	automatic mode engaged;
- *  		(default operation mode of the ThinkPad)
- * 		fan level is ignored in this mode.
- *	 6	disengage mode (takes precedence over bit 7);
- *		not available on all thinkpads.  May disable
- *		the tachometer, and speeds up fan to 100% duty-cycle,
- *		which speeds it up far above the standard RPM
- *		levels.  It is not impossible that it could cause
- *		hardware damage.
- *	5-3	unused in some models.  Extra bits for fan level
- *		in others, but still useless as all values above
- *		7 map to the same speed as level 7 in these models.
- *	2-0	fan level (0..7 usually)
- *			0x00 = stop
- * 			0x07 = max (set when temperatures critical)
- * 		Some ThinkPads may have other levels, see
- * 		IBMACPI_FAN_WR_ACPI_FANS (X31/X40/X41)
- *
- *	FIRMWARE BUG: on some models, EC 0x2f might not be initialized at
- *	boot. Apparently the EC does not intialize it, so unless ACPI DSDT
- *	does so, its initial value is meaningless (0x07).
- *
- *	For firmware bugs, refer to:
- *	http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues
- *
- * 	----
- *
- *	ThinkPad EC register 0x84 (LSB), 0x85 (MSB):
- *	Main fan tachometer reading (in RPM)
- *
- *	This register is present on all ThinkPads with a new-style EC, and
- *	it is known not to be present on the A21m/e, and T22, as there is
- *	something else in offset 0x84 according to the ACPI DSDT.  Other
- *	ThinkPads from this same time period (and earlier) probably lack the
- *	tachometer as well.
- *
- *	Unfortunately a lot of ThinkPads with new-style ECs but whose firwmare
- *	was never fixed by IBM to report the EC firmware version string
- *	probably support the tachometer (like the early X models), so
- *	detecting it is quite hard.  We need more data to know for sure.
- *
- *	FIRMWARE BUG: always read 0x84 first, otherwise incorrect readings
- *	might result.
- *
- *	FIRMWARE BUG: when EC 0x2f bit 6 is set (disengaged mode), this
- *	register is not invalidated in ThinkPads that disable tachometer
- *	readings.  Thus, the tachometer readings go stale.
- *
- *	For firmware bugs, refer to:
- *	http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues
- *
- * IBMACPI_FAN_WR_ACPI_FANS:
- *	ThinkPad X31, X40, X41.  Not available in the X60.
- *
- *	FANS ACPI handle: takes three arguments: low speed, medium speed,
- *	high speed.  ACPI DSDT seems to map these three speeds to levels
- *	as follows: STOP LOW LOW MED MED HIGH HIGH HIGH HIGH
- *	(this map is stored on FAN0..FAN8 as "0,1,1,2,2,3,3,3,3")
- *
- * 	The speeds are stored on handles
- * 	(FANA:FAN9), (FANC:FANB), (FANE:FAND).
- *
- * 	There are three default speed sets, acessible as handles:
- * 	FS1L,FS1M,FS1H; FS2L,FS2M,FS2H; FS3L,FS3M,FS3H
- *
- * 	ACPI DSDT switches which set is in use depending on various
- * 	factors.
- *
- * 	IBMACPI_FAN_WR_TPEC is also available and should be used to
- * 	command the fan.  The X31/X40/X41 seems to have 8 fan levels,
- * 	but the ACPI tables just mention level 7.
+/*************************************************************************
+ * ACPI helpers
  */
 
-static char *ibm_thinkpad_ec_found = NULL;
-
-static struct proc_dir_entry *proc_dir = NULL;
-
-static struct backlight_device *ibm_backlight_device = NULL;
-
 static int acpi_evalf(acpi_handle handle,
 		      void *res, char *method, char *fmt, ...)
 {
@@ -371,6 +228,203 @@ static void __unused acpi_print_int(acpi_handle handle, char *method)
 		printk(IBM_ERR "error calling %s\n", method);
 }
 
+static int acpi_ec_read(int i, u8 * p)
+{
+	int v;
+
+	if (ecrd_handle) {
+		if (!acpi_evalf(ecrd_handle, &v, NULL, "dd", i))
+			return 0;
+		*p = v;
+	} else {
+		if (ec_read(i, p) < 0)
+			return 0;
+	}
+
+	return 1;
+}
+
+static int acpi_ec_write(int i, u8 v)
+{
+	if (ecwr_handle) {
+		if (!acpi_evalf(ecwr_handle, NULL, NULL, "vdd", i, v))
+			return 0;
+	} else {
+		if (ec_write(i, v) < 0)
+			return 0;
+	}
+
+	return 1;
+}
+
+static int _sta(acpi_handle handle)
+{
+	int status;
+
+	if (!handle || !acpi_evalf(handle, &status, "_STA", "d"))
+		status = 0;
+
+	return status;
+}
+
+/*************************************************************************
+ * ACPI device model
+ */
+
+static void __init ibm_handle_init(char *name,
+				   acpi_handle * handle, acpi_handle parent,
+				   char **paths, int num_paths, char **path)
+{
+	int i;
+	acpi_status status;
+
+	for (i = 0; i < num_paths; i++) {
+		status = acpi_get_handle(parent, paths[i], handle);
+		if (ACPI_SUCCESS(status)) {
+			*path = paths[i];
+			return;
+		}
+	}
+
+	*handle = NULL;
+}
+
+static void dispatch_notify(acpi_handle handle, u32 event, void *data)
+{
+	struct ibm_struct *ibm = data;
+
+	if (!ibm || !ibm->notify)
+		return;
+
+	ibm->notify(ibm, event);
+}
+
+static int __init setup_notify(struct ibm_struct *ibm)
+{
+	acpi_status status;
+	int ret;
+
+	if (!*ibm->handle)
+		return 0;
+
+	ret = acpi_bus_get_device(*ibm->handle, &ibm->device);
+	if (ret < 0) {
+		printk(IBM_ERR "%s device not present\n", ibm->name);
+		return -ENODEV;
+	}
+
+	acpi_driver_data(ibm->device) = ibm;
+	sprintf(acpi_device_class(ibm->device), "%s/%s", IBM_NAME, ibm->name);
+
+	status = acpi_install_notify_handler(*ibm->handle, ibm->type,
+					     dispatch_notify, ibm);
+	if (ACPI_FAILURE(status)) {
+		if (status == AE_ALREADY_EXISTS) {
+			printk(IBM_NOTICE "another device driver is already handling %s events\n",
+				ibm->name);
+		} else {
+			printk(IBM_ERR "acpi_install_notify_handler(%s) failed: %d\n",
+				ibm->name, status);
+		}
+		return -ENODEV;
+	}
+	ibm->notify_installed = 1;
+	return 0;
+}
+
+static int __init ibm_device_add(struct acpi_device *device)
+{
+	return 0;
+}
+
+static int __init register_ibmacpi_subdriver(struct ibm_struct *ibm)
+{
+	int ret;
+
+	ibm->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL);
+	if (!ibm->driver) {
+		printk(IBM_ERR "kmalloc(ibm->driver) failed\n");
+		return -1;
+	}
+
+	sprintf(ibm->driver->name, "%s_%s", IBM_NAME, ibm->name);
+	ibm->driver->ids = ibm->hid;
+	ibm->driver->ops.add = &ibm_device_add;
+
+	ret = acpi_bus_register_driver(ibm->driver);
+	if (ret < 0) {
+		printk(IBM_ERR "acpi_bus_register_driver(%s) failed: %d\n",
+		       ibm->hid, ret);
+		kfree(ibm->driver);
+	}
+
+	return ret;
+}
+
+
+/****************************************************************************
+ ****************************************************************************
+ *
+ * Procfs Helpers
+ *
+ ****************************************************************************
+ ****************************************************************************/
+
+static int dispatch_read(char *page, char **start, off_t off, int count,
+			 int *eof, void *data)
+{
+	struct ibm_struct *ibm = data;
+	int len;
+
+	if (!ibm || !ibm->read)
+		return -EINVAL;
+
+	len = ibm->read(page);
+	if (len < 0)
+		return len;
+
+	if (len <= off + count)
+		*eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len > count)
+		len = count;
+	if (len < 0)
+		len = 0;
+
+	return len;
+}
+
+static int dispatch_write(struct file *file, const char __user * userbuf,
+			  unsigned long count, void *data)
+{
+	struct ibm_struct *ibm = data;
+	char *kernbuf;
+	int ret;
+
+	if (!ibm || !ibm->write)
+		return -EINVAL;
+
+	kernbuf = kmalloc(count + 2, GFP_KERNEL);
+	if (!kernbuf)
+		return -ENOMEM;
+
+	if (copy_from_user(kernbuf, userbuf, count)) {
+		kfree(kernbuf);
+		return -EFAULT;
+	}
+
+	kernbuf[count] = 0;
+	strcat(kernbuf, ",");
+	ret = ibm->write(kernbuf);
+	if (ret == 0)
+		ret = count;
+
+	kfree(kernbuf);
+
+	return ret;
+}
+
 static char *next_cmd(char **cmds)
 {
 	char *start = *cmds;
@@ -387,6 +441,19 @@ static char *next_cmd(char **cmds)
 	return start;
 }
 
+
+/****************************************************************************
+ ****************************************************************************
+ *
+ * Subdrivers
+ *
+ ****************************************************************************
+ ****************************************************************************/
+
+/*************************************************************************
+ * ibm-acpi init subdriver
+ */
+
 static int ibm_acpi_driver_init(void)
 {
 	printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION);
@@ -409,11 +476,51 @@ static int ibm_acpi_driver_read(char *p)
 	return len;
 }
 
+/*************************************************************************
+ * Hotkey subdriver
+ */
+
 static int hotkey_supported;
 static int hotkey_mask_supported;
 static int hotkey_orig_status;
 static int hotkey_orig_mask;
 
+static int hotkey_init(void)
+{
+	/* hotkey not supported on 570 */
+	hotkey_supported = hkey_handle != NULL;
+
+	if (hotkey_supported) {
+		/* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
+		   A30, R30, R31, T20-22, X20-21, X22-24 */
+		hotkey_mask_supported =
+		    acpi_evalf(hkey_handle, NULL, "DHKN", "qv");
+
+		if (!hotkey_get(&hotkey_orig_status, &hotkey_orig_mask))
+			return -ENODEV;
+	}
+
+	return 0;
+}
+
+static void hotkey_exit(void)
+{
+	if (hotkey_supported)
+		hotkey_set(hotkey_orig_status, hotkey_orig_mask);
+}
+
+static void hotkey_notify(struct ibm_struct *ibm, u32 event)
+{
+	int hkey;
+
+	if (acpi_evalf(hkey_handle, &hkey, "MHKP", "d"))
+		acpi_bus_generate_event(ibm->device, event, hkey);
+	else {
+		printk(IBM_ERR "unknown hotkey event %d\n", event);
+		acpi_bus_generate_event(ibm->device, event, 0);
+	}
+}
+
 static int hotkey_get(int *status, int *mask)
 {
 	if (!acpi_evalf(hkey_handle, status, "DHKC", "d"))
@@ -444,24 +551,6 @@ static int hotkey_set(int status, int mask)
 	return 1;
 }
 
-static int hotkey_init(void)
-{
-	/* hotkey not supported on 570 */
-	hotkey_supported = hkey_handle != NULL;
-
-	if (hotkey_supported) {
-		/* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
-		   A30, R30, R31, T20-22, X20-21, X22-24 */
-		hotkey_mask_supported =
-		    acpi_evalf(hkey_handle, NULL, "DHKN", "qv");
-
-		if (!hotkey_get(&hotkey_orig_status, &hotkey_orig_mask))
-			return -ENODEV;
-	}
-
-	return 0;
-}
-
 static int hotkey_read(char *p)
 {
 	int status, mask;
@@ -523,23 +612,9 @@ static int hotkey_write(char *buf)
 	return 0;
 }
 
-static void hotkey_exit(void)
-{
-	if (hotkey_supported)
-		hotkey_set(hotkey_orig_status, hotkey_orig_mask);
-}
-
-static void hotkey_notify(struct ibm_struct *ibm, u32 event)
-{
-	int hkey;
-
-	if (acpi_evalf(hkey_handle, &hkey, "MHKP", "d"))
-		acpi_bus_generate_event(ibm->device, event, hkey);
-	else {
-		printk(IBM_ERR "unknown hotkey event %d\n", event);
-		acpi_bus_generate_event(ibm->device, event, 0);
-	}
-}
+/*************************************************************************
+ * Bluetooth subdriver
+ */
 
 static int bluetooth_supported;
 
@@ -606,6 +681,10 @@ static int bluetooth_write(char *buf)
 	return 0;
 }
 
+/*************************************************************************
+ * Wan subdriver
+ */
+
 static int wan_supported;
 
 static int wan_init(void)
@@ -668,9 +747,22 @@ static int wan_write(char *buf)
 	return 0;
 }
 
+/*************************************************************************
+ * Video subdriver
+ */
+
 static enum video_access_mode video_supported;
 static int video_orig_autosw;
 
+IBM_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA",	/* 570 */
+	   "\\_SB.PCI0.AGP0.VID0",	/* 600e/x, 770x */
+	   "\\_SB.PCI0.VID0",	/* 770e */
+	   "\\_SB.PCI0.VID",	/* A21e, G4x, R50e, X30, X40 */
+	   "\\_SB.PCI0.AGP.VID",	/* all others */
+	   );				/* R30, R31 */
+
+IBM_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID");	/* G41 */
+
 static int video_init(void)
 {
 	int ivga;
@@ -695,6 +787,11 @@ static int video_init(void)
 	return 0;
 }
 
+static void video_exit(void)
+{
+	acpi_evalf(vid_handle, NULL, "_DOS", "vd", video_orig_autosw);
+}
+
 static int video_status(void)
 {
 	int status = 0;
@@ -736,33 +833,6 @@ static int video_autosw(void)
 	return autosw & 1;
 }
 
-static int video_read(char *p)
-{
-	int status = video_status();
-	int autosw = video_autosw();
-	int len = 0;
-
-	if (!video_supported) {
-		len += sprintf(p + len, "status:\t\tnot supported\n");
-		return len;
-	}
-
-	len += sprintf(p + len, "status:\t\tsupported\n");
-	len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0));
-	len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1));
-	if (video_supported == IBMACPI_VIDEO_NEW)
-		len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3));
-	len += sprintf(p + len, "auto:\t\t%s\n", enabled(autosw, 0));
-	len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable\n");
-	len += sprintf(p + len, "commands:\tcrt_enable, crt_disable\n");
-	if (video_supported == IBMACPI_VIDEO_NEW)
-		len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable\n");
-	len += sprintf(p + len, "commands:\tauto_enable, auto_disable\n");
-	len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n");
-
-	return len;
-}
-
 static int video_switch(void)
 {
 	int autosw = video_autosw();
@@ -812,6 +882,33 @@ static int video_switch2(int status)
 	return ret;
 }
 
+static int video_read(char *p)
+{
+	int status = video_status();
+	int autosw = video_autosw();
+	int len = 0;
+
+	if (!video_supported) {
+		len += sprintf(p + len, "status:\t\tnot supported\n");
+		return len;
+	}
+
+	len += sprintf(p + len, "status:\t\tsupported\n");
+	len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0));
+	len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1));
+	if (video_supported == IBMACPI_VIDEO_NEW)
+		len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3));
+	len += sprintf(p + len, "auto:\t\t%s\n", enabled(autosw, 0));
+	len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable\n");
+	len += sprintf(p + len, "commands:\tcrt_enable, crt_disable\n");
+	if (video_supported == IBMACPI_VIDEO_NEW)
+		len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable\n");
+	len += sprintf(p + len, "commands:\tauto_enable, auto_disable\n");
+	len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n");
+
+	return len;
+}
+
 static int video_write(char *buf)
 {
 	char *cmd;
@@ -862,14 +959,16 @@ static int video_write(char *buf)
 	return 0;
 }
 
-static void video_exit(void)
-{
-	acpi_evalf(vid_handle, NULL, "_DOS", "vd", video_orig_autosw);
-}
+/*************************************************************************
+ * Light (thinklight) subdriver
+ */
 
 static int light_supported;
 static int light_status_supported;
 
+IBM_HANDLE(lght, root, "\\LGHT");	/* A21e, A2xm/p, T20-22, X20-21 */
+IBM_HANDLE(ledb, ec, "LEDB");		/* G4x */
+
 static int light_init(void)
 {
 	/* light not supported on 570, 600e/x, 770e, 770x, G4x, R30, R31 */
@@ -933,21 +1032,45 @@ static int light_write(char *buf)
 	return 0;
 }
 
-#if defined(CONFIG_ACPI_IBM_DOCK) || defined(CONFIG_ACPI_IBM_BAY)
-static int _sta(acpi_handle handle)
-{
-	int status;
-
-	if (!handle || !acpi_evalf(handle, &status, "_STA", "d"))
-		status = 0;
+/*************************************************************************
+ * Dock subdriver
+ */
 
-	return status;
-}
-#endif
+/* don't list other alternatives as we install a notify handler on the 570 */
+IBM_HANDLE(pci, root, "\\_SB.PCI");	/* 570 */
 
 #ifdef CONFIG_ACPI_IBM_DOCK
+
+IBM_HANDLE(dock, root, "\\_SB.GDCK",	/* X30, X31, X40 */
+	   "\\_SB.PCI0.DOCK",	/* 600e/x,770e,770x,A2xm/p,T20-22,X20-21 */
+	   "\\_SB.PCI0.PCI1.DOCK",	/* all others */
+	   "\\_SB.PCI.ISA.SLCE",	/* 570 */
+    );				/* A21e,G4x,R30,R31,R32,R40,R40e,R50e */
+
 #define dock_docked() (_sta(dock_handle) & 1)
 
+static void dock_notify(struct ibm_struct *ibm, u32 event)
+{
+	int docked = dock_docked();
+	int pci = ibm->hid && strstr(ibm->hid, IBM_PCI_HID);
+
+	if (event == 1 && !pci)	/* 570 */
+		acpi_bus_generate_event(ibm->device, event, 1);	/* button */
+	else if (event == 1 && pci)	/* 570 */
+		acpi_bus_generate_event(ibm->device, event, 3);	/* dock */
+	else if (event == 3 && docked)
+		acpi_bus_generate_event(ibm->device, event, 1);	/* button */
+	else if (event == 3 && !docked)
+		acpi_bus_generate_event(ibm->device, event, 2);	/* undock */
+	else if (event == 0 && docked)
+		acpi_bus_generate_event(ibm->device, event, 3);	/* dock */
+	else {
+		printk(IBM_ERR "unknown dock event %d, status %d\n",
+		       event, _sta(dock_handle));
+		acpi_bus_generate_event(ibm->device, event, 0);	/* unknown */
+	}
+}
+
 static int dock_read(char *p)
 {
 	int len = 0;
@@ -987,28 +1110,11 @@ static int dock_write(char *buf)
 	return 0;
 }
 
-static void dock_notify(struct ibm_struct *ibm, u32 event)
-{
-	int docked = dock_docked();
-	int pci = ibm->hid && strstr(ibm->hid, IBM_PCI_HID);
+#endif /* CONFIG_ACPI_IBM_DOCK */
 
-	if (event == 1 && !pci)	/* 570 */
-		acpi_bus_generate_event(ibm->device, event, 1);	/* button */
-	else if (event == 1 && pci)	/* 570 */
-		acpi_bus_generate_event(ibm->device, event, 3);	/* dock */
-	else if (event == 3 && docked)
-		acpi_bus_generate_event(ibm->device, event, 1);	/* button */
-	else if (event == 3 && !docked)
-		acpi_bus_generate_event(ibm->device, event, 2);	/* undock */
-	else if (event == 0 && docked)
-		acpi_bus_generate_event(ibm->device, event, 3);	/* dock */
-	else {
-		printk(IBM_ERR "unknown dock event %d, status %d\n",
-		       event, _sta(dock_handle));
-		acpi_bus_generate_event(ibm->device, event, 0);	/* unknown */
-	}
-}
-#endif
+/*************************************************************************
+ * Bay subdriver
+ */
 
 #ifdef CONFIG_ACPI_IBM_BAY
 static int bay_status_supported;
@@ -1016,6 +1122,21 @@ static int bay_status2_supported;
 static int bay_eject_supported;
 static int bay_eject2_supported;
 
+IBM_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST",	/* 570 */
+	   "\\_SB.PCI0.IDE0.IDES.IDSM",	/* 600e/x, 770e, 770x */
+	   "\\_SB.PCI0.SATA.SCND.MSTR",	/* T60, X60, Z60 */
+	   "\\_SB.PCI0.IDE0.SCND.MSTR",	/* all others */
+	   );				/* A21e, R30, R31 */
+IBM_HANDLE(bay_ej, bay, "_EJ3",	/* 600e/x, A2xm/p, A3x */
+	   "_EJ0",		/* all others */
+	   );			/* 570,A21e,G4x,R30,R31,R32,R40e,R50e */
+IBM_HANDLE(bay2, root, "\\_SB.PCI0.IDE0.PRIM.SLAV",	/* A3x, R32 */
+	   "\\_SB.PCI0.IDE0.IDEP.IDPS",	/* 600e/x, 770e, 770x */
+	   );				/* all others */
+IBM_HANDLE(bay2_ej, bay2, "_EJ3",	/* 600e/x, 770e, A3x */
+	   "_EJ0",			/* 770x */
+	   );				/* all others */
+
 static int bay_init(void)
 {
 	bay_status_supported = bay_handle &&
@@ -1031,6 +1152,11 @@ static int bay_init(void)
 	return 0;
 }
 
+static void bay_notify(struct ibm_struct *ibm, u32 event)
+{
+	acpi_bus_generate_event(ibm->device, event, 0);
+}
+
 #define bay_occupied(b) (_sta(b##_handle) & 1)
 
 static int bay_read(char *p)
@@ -1081,12 +1207,19 @@ static int bay_write(char *buf)
 
 	return 0;
 }
+#endif /* CONFIG_ACPI_IBM_BAY */
 
-static void bay_notify(struct ibm_struct *ibm, u32 event)
+/*************************************************************************
+ * CMOS subdriver
+ */
+
+static int cmos_eval(int cmos_cmd)
 {
-	acpi_bus_generate_event(ibm->device, event, 0);
+	if (cmos_handle)
+		return acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd);
+	else
+		return 1;
 }
-#endif /* CONFIG_ACPI_IBM_BAY */
 
 static int cmos_read(char *p)
 {
@@ -1104,14 +1237,6 @@ static int cmos_read(char *p)
 	return len;
 }
 
-static int cmos_eval(int cmos_cmd)
-{
-	if (cmos_handle)
-		return acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd);
-	else
-		return 1;
-}
-
 static int cmos_write(char *buf)
 {
 	char *cmd;
@@ -1134,8 +1259,18 @@ static int cmos_write(char *buf)
 	return 0;
 }
 
+
+/*************************************************************************
+ * LED subdriver
+ */
+
 static enum led_access_mode led_supported;
 
+IBM_HANDLE(led, ec, "SLED",	/* 570 */
+	   "SYSL",		/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
+	   "LED",		/* all others */
+	   );			/* R30, R31 */
+
 static int led_init(void)
 {
 	if (!led_handle)
@@ -1242,6 +1377,12 @@ static int led_write(char *buf)
 	return 0;
 }
 
+/*************************************************************************
+ * Beep subdriver
+ */
+
+IBM_HANDLE(beep, ec, "BEEP");	/* all except R30, R31 */
+
 static int beep_read(char *p)
 {
 	int len = 0;
@@ -1277,34 +1418,9 @@ static int beep_write(char *buf)
 	return 0;
 }
 
-static int acpi_ec_read(int i, u8 * p)
-{
-	int v;
-
-	if (ecrd_handle) {
-		if (!acpi_evalf(ecrd_handle, &v, NULL, "dd", i))
-			return 0;
-		*p = v;
-	} else {
-		if (ec_read(i, p) < 0)
-			return 0;
-	}
-
-	return 1;
-}
-
-static int acpi_ec_write(int i, u8 v)
-{
-	if (ecwr_handle) {
-		if (!acpi_evalf(ecwr_handle, NULL, NULL, "vdd", i, v))
-			return 0;
-	} else {
-		if (ec_write(i, v) < 0)
-			return 0;
-	}
-
-	return 1;
-}
+/*************************************************************************
+ * Thermal subdriver
+ */
 
 static enum thermal_access_mode thermal_read_mode;
 
@@ -1446,6 +1562,10 @@ static int thermal_read(char *p)
 	return len;
 }
 
+/*************************************************************************
+ * EC Dump subdriver
+ */
+
 static u8 ecdump_regs[256];
 
 static int ecdump_read(char *p)
@@ -1505,6 +1625,55 @@ static int ecdump_write(char *buf)
 	return 0;
 }
 
+/*************************************************************************
+ * Backlight/brightness subdriver
+ */
+
+static struct backlight_device *ibm_backlight_device = NULL;
+
+static struct backlight_ops ibm_backlight_data = {
+        .get_brightness = brightness_get,
+        .update_status  = brightness_update_status,
+};
+
+static int brightness_init(void)
+{
+	int b;
+
+	b = brightness_get(NULL);
+	if (b < 0)
+		return b;
+
+	ibm_backlight_device = backlight_device_register("ibm", NULL, NULL,
+							 &ibm_backlight_data);
+	if (IS_ERR(ibm_backlight_device)) {
+		printk(IBM_ERR "Could not register backlight device\n");
+		return PTR_ERR(ibm_backlight_device);
+	}
+
+	ibm_backlight_device->props.max_brightness = 7;
+	ibm_backlight_device->props.brightness = b;
+	backlight_update_status(ibm_backlight_device);
+
+	return 0;
+}
+
+static void brightness_exit(void)
+{
+	if (ibm_backlight_device) {
+		backlight_device_unregister(ibm_backlight_device);
+		ibm_backlight_device = NULL;
+	}
+}
+
+static int brightness_update_status(struct backlight_device *bd)
+{
+	return brightness_set(
+		(bd->props.fb_blank == FB_BLANK_UNBLANK &&
+		 bd->props.power == FB_BLANK_UNBLANK) ?
+				bd->props.brightness : 0);
+}
+
 static int brightness_get(struct backlight_device *bd)
 {
 	u8 level;
@@ -1516,23 +1685,6 @@ static int brightness_get(struct backlight_device *bd)
 	return level;
 }
 
-static int brightness_read(char *p)
-{
-	int len = 0;
-	int level;
-
-	if ((level = brightness_get(NULL)) < 0) {
-		len += sprintf(p + len, "level:\t\tunreadable\n");
-	} else {
-		len += sprintf(p + len, "level:\t\t%d\n", level & 0x7);
-		len += sprintf(p + len, "commands:\tup, down\n");
-		len += sprintf(p + len, "commands:\tlevel <level>"
-			       " (<level> is 0-7)\n");
-	}
-
-	return len;
-}
-
 static int brightness_set(int value)
 {
 	int cmos_cmd, inc, i;
@@ -1540,8 +1692,7 @@ static int brightness_set(int value)
 
 	value &= 7;
 
-	cmos_cmd = value > current_value ?
-		   TP_CMOS_BRIGHTNESS_UP : TP_CMOS_BRIGHTNESS_DOWN;
+	cmos_cmd = value > current_value ? TP_CMOS_BRIGHTNESS_UP : TP_CMOS_BRIGHTNESS_DOWN;
 	inc = value > current_value ? 1 : -1;
 	for (i = current_value; i != value; i += inc) {
 		if (!cmos_eval(cmos_cmd))
@@ -1553,6 +1704,23 @@ static int brightness_set(int value)
 	return 0;
 }
 
+static int brightness_read(char *p)
+{
+	int len = 0;
+	int level;
+
+	if ((level = brightness_get(NULL)) < 0) {
+		len += sprintf(p + len, "level:\t\tunreadable\n");
+	} else {
+		len += sprintf(p + len, "level:\t\t%d\n", level & 0x7);
+		len += sprintf(p + len, "commands:\tup, down\n");
+		len += sprintf(p + len, "commands:\tlevel <level>"
+			       " (<level> is 0-7)\n");
+	}
+
+	return len;
+}
+
 static int brightness_write(char *buf)
 {
 	int level;
@@ -1580,48 +1748,9 @@ static int brightness_write(char *buf)
 	return 0;
 }
 
-static int brightness_update_status(struct backlight_device *bd)
-{
-	return brightness_set(
-		(bd->props.fb_blank == FB_BLANK_UNBLANK &&
-		 bd->props.power == FB_BLANK_UNBLANK) ?
-				bd->props.brightness : 0);
-}
-
-static struct backlight_ops ibm_backlight_data = {
-        .get_brightness = brightness_get,
-        .update_status  = brightness_update_status,
-};
-
-static int brightness_init(void)
-{
-	int b;
-
-	b = brightness_get(NULL);
-	if (b < 0)
-		return b;
-
-	ibm_backlight_device = backlight_device_register("ibm", NULL, NULL,
-							 &ibm_backlight_data);
-	if (IS_ERR(ibm_backlight_device)) {
-		printk(IBM_ERR "Could not register backlight device\n");
-		return PTR_ERR(ibm_backlight_device);
-	}
-
-	ibm_backlight_device->props.max_brightness = 7;
-	ibm_backlight_device->props.brightness = b;
-	backlight_update_status(ibm_backlight_device);
-
-	return 0;
-}
-
-static void brightness_exit(void)
-{
-	if (ibm_backlight_device) {
-		backlight_device_unregister(ibm_backlight_device);
-		ibm_backlight_device = NULL;
-	}
-}
+/*************************************************************************
+ * Volume subdriver
+ */
 
 static int volume_read(char *p)
 {
@@ -1673,8 +1802,7 @@ static int volume_write(char *buf)
 			return -EINVAL;
 
 		if (new_level != level) {	/* mute doesn't change */
-			cmos_cmd = new_level > level ?
-					TP_CMOS_VOLUME_UP : TP_CMOS_VOLUME_DOWN;
+			cmos_cmd = new_level > level ? TP_CMOS_VOLUME_UP : TP_CMOS_VOLUME_DOWN;
 			inc = new_level > level ? 1 : -1;
 
 			if (mute && (!cmos_eval(cmos_cmd) ||
@@ -1693,8 +1821,7 @@ static int volume_write(char *buf)
 		}
 
 		if (new_mute != mute) {	/* level doesn't change */
-			cmos_cmd = new_mute ?
-				   TP_CMOS_VOLUME_MUTE : TP_CMOS_VOLUME_UP;
+			cmos_cmd = new_mute ? TP_CMOS_VOLUME_MUTE : TP_CMOS_VOLUME_UP;
 
 			if (!cmos_eval(cmos_cmd) ||
 			    !acpi_ec_write(volume_offset, level + new_mute))
@@ -1705,6 +1832,111 @@ static int volume_write(char *buf)
 	return 0;
 }
 
+
+/*************************************************************************
+ * Fan subdriver
+ */
+
+/*
+ * FAN ACCESS MODES
+ *
+ * IBMACPI_FAN_RD_ACPI_GFAN:
+ * 	ACPI GFAN method: returns fan level
+ *
+ * 	see IBMACPI_FAN_WR_ACPI_SFAN
+ * 	EC 0x2f not available if GFAN exists
+ *
+ * IBMACPI_FAN_WR_ACPI_SFAN:
+ * 	ACPI SFAN method: sets fan level, 0 (stop) to 7 (max)
+ *
+ * 	EC 0x2f might be available *for reading*, but never for writing.
+ *
+ * IBMACPI_FAN_WR_TPEC:
+ * 	ThinkPad EC register 0x2f (HFSP): fan control loop mode Supported
+ * 	on almost all ThinkPads
+ *
+ * 	Fan speed changes of any sort (including those caused by the
+ * 	disengaged mode) are usually done slowly by the firmware as the
+ * 	maximum ammount of fan duty cycle change per second seems to be
+ * 	limited.
+ *
+ * 	Reading is not available if GFAN exists.
+ * 	Writing is not available if SFAN exists.
+ *
+ * 	Bits
+ *	 7	automatic mode engaged;
+ *  		(default operation mode of the ThinkPad)
+ * 		fan level is ignored in this mode.
+ *	 6	disengage mode (takes precedence over bit 7);
+ *		not available on all thinkpads.  May disable
+ *		the tachometer, and speeds up fan to 100% duty-cycle,
+ *		which speeds it up far above the standard RPM
+ *		levels.  It is not impossible that it could cause
+ *		hardware damage.
+ *	5-3	unused in some models.  Extra bits for fan level
+ *		in others, but still useless as all values above
+ *		7 map to the same speed as level 7 in these models.
+ *	2-0	fan level (0..7 usually)
+ *			0x00 = stop
+ * 			0x07 = max (set when temperatures critical)
+ * 		Some ThinkPads may have other levels, see
+ * 		IBMACPI_FAN_WR_ACPI_FANS (X31/X40/X41)
+ *
+ *	FIRMWARE BUG: on some models, EC 0x2f might not be initialized at
+ *	boot. Apparently the EC does not intialize it, so unless ACPI DSDT
+ *	does so, its initial value is meaningless (0x07).
+ *
+ *	For firmware bugs, refer to:
+ *	http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues
+ *
+ * 	----
+ *
+ *	ThinkPad EC register 0x84 (LSB), 0x85 (MSB):
+ *	Main fan tachometer reading (in RPM)
+ *
+ *	This register is present on all ThinkPads with a new-style EC, and
+ *	it is known not to be present on the A21m/e, and T22, as there is
+ *	something else in offset 0x84 according to the ACPI DSDT.  Other
+ *	ThinkPads from this same time period (and earlier) probably lack the
+ *	tachometer as well.
+ *
+ *	Unfortunately a lot of ThinkPads with new-style ECs but whose firwmare
+ *	was never fixed by IBM to report the EC firmware version string
+ *	probably support the tachometer (like the early X models), so
+ *	detecting it is quite hard.  We need more data to know for sure.
+ *
+ *	FIRMWARE BUG: always read 0x84 first, otherwise incorrect readings
+ *	might result.
+ *
+ *	FIRMWARE BUG: when EC 0x2f bit 6 is set (disengaged mode), this
+ *	register is not invalidated in ThinkPads that disable tachometer
+ *	readings.  Thus, the tachometer readings go stale.
+ *
+ *	For firmware bugs, refer to:
+ *	http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues
+ *
+ * IBMACPI_FAN_WR_ACPI_FANS:
+ *	ThinkPad X31, X40, X41.  Not available in the X60.
+ *
+ *	FANS ACPI handle: takes three arguments: low speed, medium speed,
+ *	high speed.  ACPI DSDT seems to map these three speeds to levels
+ *	as follows: STOP LOW LOW MED MED HIGH HIGH HIGH HIGH
+ *	(this map is stored on FAN0..FAN8 as "0,1,1,2,2,3,3,3,3")
+ *
+ * 	The speeds are stored on handles
+ * 	(FANA:FAN9), (FANC:FANB), (FANE:FAND).
+ *
+ * 	There are three default speed sets, acessible as handles:
+ * 	FS1L,FS1M,FS1H; FS2L,FS2M,FS2H; FS3L,FS3M,FS3H
+ *
+ * 	ACPI DSDT switches which set is in use depending on various
+ * 	factors.
+ *
+ * 	IBMACPI_FAN_WR_TPEC is also available and should be used to
+ * 	command the fan.  The X31/X40/X41 seems to have 8 fan levels,
+ * 	but the ACPI tables just mention level 7.
+ */
+
 static enum fan_status_access_mode fan_status_access_mode;
 static enum fan_control_access_mode fan_control_access_mode;
 static enum fan_control_commands fan_control_commands;
@@ -1716,6 +1948,14 @@ static void fan_watchdog_fire(struct work_struct *ignored);
 static int fan_watchdog_maxinterval;
 static DECLARE_DELAYED_WORK(fan_watchdog_task, fan_watchdog_fire);
 
+IBM_HANDLE(fans, ec, "FANS");	/* X31, X40, X41 */
+IBM_HANDLE(gfan, ec, "GFAN",	/* 570 */
+	   "\\FSPD",		/* 600e/x, 770e, 770x */
+	   );			/* all others */
+IBM_HANDLE(sfan, ec, "SFAN",	/* 570 */
+	   "JFNS",		/* 770x-JL */
+	   );			/* all others */
+
 static int fan_init(void)
 {
 	fan_status_access_mode = IBMACPI_FAN_NONE;
@@ -1831,6 +2071,12 @@ static int fan_get_status(u8 *status)
 	return 0;
 }
 
+static void fan_exit(void)
+{
+	cancel_delayed_work(&fan_watchdog_task);
+	flush_scheduled_work();
+}
+
 static int fan_get_speed(unsigned int *speed)
 {
 	u8 hi, lo;
@@ -1854,10 +2100,14 @@ static int fan_get_speed(unsigned int *speed)
 	return 0;
 }
 
-static void fan_exit(void)
+static void fan_watchdog_fire(struct work_struct *ignored)
 {
-	cancel_delayed_work(&fan_watchdog_task);
-	flush_scheduled_work();
+	printk(IBM_NOTICE "fan watchdog: enabling fan\n");
+	if (fan_set_enable()) {
+		printk(IBM_ERR "fan watchdog: error while enabling fan\n");
+		/* reschedule for later */
+		fan_watchdog_reset();
+	}
 }
 
 static void fan_watchdog_reset(void)
@@ -1879,90 +2129,6 @@ static void fan_watchdog_reset(void)
 		fan_watchdog_active = 0;
 }
 
-static int fan_read(char *p)
-{
-	int len = 0;
-	int rc;
-	u8 status;
-	unsigned int speed = 0;
-
-	switch (fan_status_access_mode) {
-	case IBMACPI_FAN_RD_ACPI_GFAN:
-		/* 570, 600e/x, 770e, 770x */
-		if ((rc = fan_get_status(&status)) < 0)
-			return rc;
-
-		len += sprintf(p + len, "status:\t\t%s\n"
-			       "level:\t\t%d\n",
-			       (status != 0) ? "enabled" : "disabled", status);
-		break;
-
-	case IBMACPI_FAN_RD_TPEC:
-		/* all except 570, 600e/x, 770e, 770x */
-		if ((rc = fan_get_status(&status)) < 0)
-			return rc;
-
-		if (unlikely(!fan_control_status_known)) {
-			if (status != fan_control_initial_status)
-				fan_control_status_known = 1;
-			else
-				/* Return most likely status. In fact, it
-				 * might be the only possible status */
-				status = IBMACPI_FAN_EC_AUTO;
-		}
-
-		len += sprintf(p + len, "status:\t\t%s\n",
-			       (status != 0) ? "enabled" : "disabled");
-
-		/* No ThinkPad boots on disengaged mode, we can safely
-		 * assume the tachometer is online if fan control status
-		 * was unknown */
-		if ((rc = fan_get_speed(&speed)) < 0)
-			return rc;
-
-		len += sprintf(p + len, "speed:\t\t%d\n", speed);
-
-		if (status & IBMACPI_FAN_EC_DISENGAGED)
-			/* Disengaged mode takes precedence */
-			len += sprintf(p + len, "level:\t\tdisengaged\n");
-		else if (status & IBMACPI_FAN_EC_AUTO)
-			len += sprintf(p + len, "level:\t\tauto\n");
-		else
-			len += sprintf(p + len, "level:\t\t%d\n", status);
-		break;
-
-	case IBMACPI_FAN_NONE:
-	default:
-		len += sprintf(p + len, "status:\t\tnot supported\n");
-	}
-
-	if (fan_control_commands & IBMACPI_FAN_CMD_LEVEL) {
-		len += sprintf(p + len, "commands:\tlevel <level>");
-
-		switch (fan_control_access_mode) {
-		case IBMACPI_FAN_WR_ACPI_SFAN:
-			len += sprintf(p + len, " (<level> is 0-7)\n");
-			break;
-
-		default:
-			len += sprintf(p + len, " (<level> is 0-7, "
-				       "auto, disengaged)\n");
-			break;
-		}
-	}
-
-	if (fan_control_commands & IBMACPI_FAN_CMD_ENABLE)
-		len += sprintf(p + len, "commands:\tenable, disable\n"
-			       "commands:\twatchdog <timeout> (<timeout> is 0 (off), "
-			       "1-120 (seconds))\n");
-
-	if (fan_control_commands & IBMACPI_FAN_CMD_SPEED)
-		len += sprintf(p + len, "commands:\tspeed <speed>"
-			       " (<speed> is 0-65535)\n");
-
-	return len;
-}
-
 static int fan_set_level(int level)
 {
 	switch (fan_control_access_mode) {
@@ -2074,6 +2240,90 @@ static int fan_set_speed(int speed)
 	return 0;
 }
 
+static int fan_read(char *p)
+{
+	int len = 0;
+	int rc;
+	u8 status;
+	unsigned int speed = 0;
+
+	switch (fan_status_access_mode) {
+	case IBMACPI_FAN_RD_ACPI_GFAN:
+		/* 570, 600e/x, 770e, 770x */
+		if ((rc = fan_get_status(&status)) < 0)
+			return rc;
+
+		len += sprintf(p + len, "status:\t\t%s\n"
+			       "level:\t\t%d\n",
+			       (status != 0) ? "enabled" : "disabled", status);
+		break;
+
+	case IBMACPI_FAN_RD_TPEC:
+		/* all except 570, 600e/x, 770e, 770x */
+		if ((rc = fan_get_status(&status)) < 0)
+			return rc;
+
+		if (unlikely(!fan_control_status_known)) {
+			if (status != fan_control_initial_status)
+				fan_control_status_known = 1;
+			else
+				/* Return most likely status. In fact, it
+				 * might be the only possible status */
+				status = IBMACPI_FAN_EC_AUTO;
+		}
+
+		len += sprintf(p + len, "status:\t\t%s\n",
+			       (status != 0) ? "enabled" : "disabled");
+
+		/* No ThinkPad boots on disengaged mode, we can safely
+		 * assume the tachometer is online if fan control status
+		 * was unknown */
+		if ((rc = fan_get_speed(&speed)) < 0)
+			return rc;
+
+		len += sprintf(p + len, "speed:\t\t%d\n", speed);
+
+		if (status & IBMACPI_FAN_EC_DISENGAGED)
+			/* Disengaged mode takes precedence */
+			len += sprintf(p + len, "level:\t\tdisengaged\n");
+		else if (status & IBMACPI_FAN_EC_AUTO)
+			len += sprintf(p + len, "level:\t\tauto\n");
+		else
+			len += sprintf(p + len, "level:\t\t%d\n", status);
+		break;
+
+	case IBMACPI_FAN_NONE:
+	default:
+		len += sprintf(p + len, "status:\t\tnot supported\n");
+	}
+
+	if (fan_control_commands & IBMACPI_FAN_CMD_LEVEL) {
+		len += sprintf(p + len, "commands:\tlevel <level>");
+
+		switch (fan_control_access_mode) {
+		case IBMACPI_FAN_WR_ACPI_SFAN:
+			len += sprintf(p + len, " (<level> is 0-7)\n");
+			break;
+
+		default:
+			len += sprintf(p + len, " (<level> is 0-7, "
+				       "auto, disengaged)\n");
+			break;
+		}
+	}
+
+	if (fan_control_commands & IBMACPI_FAN_CMD_ENABLE)
+		len += sprintf(p + len, "commands:\tenable, disable\n"
+			       "commands:\twatchdog <timeout> (<timeout> is 0 (off), "
+			       "1-120 (seconds))\n");
+
+	if (fan_control_commands & IBMACPI_FAN_CMD_SPEED)
+		len += sprintf(p + len, "commands:\tspeed <speed>"
+			       " (<speed> is 0-65535)\n");
+
+	return len;
+}
+
 static int fan_write_cmd_level(const char *cmd, int *rc)
 {
 	int level;
@@ -2171,16 +2421,18 @@ static int fan_write(char *buf)
 	return rc;
 }
 
-static void fan_watchdog_fire(struct work_struct *ignored)
-{
-	printk(IBM_NOTICE "fan watchdog: enabling fan\n");
-	if (fan_set_enable()) {
-		printk(IBM_ERR "fan watchdog: error while enabling fan\n");
-		/* reschedule for later */
-		fan_watchdog_reset();
-	}
-}
+/****************************************************************************
+ ****************************************************************************
+ *
+ * Infrastructure
+ *
+ ****************************************************************************
+ ****************************************************************************/
+
+/* /proc support */
+static struct proc_dir_entry *proc_dir = NULL;
 
+/* Subdriver registry */
 static struct ibm_struct ibms[] = {
 	{
 	 .name = "driver",
@@ -2301,132 +2553,9 @@ static struct ibm_struct ibms[] = {
 	 },
 };
 
-static int dispatch_read(char *page, char **start, off_t off, int count,
-			 int *eof, void *data)
-{
-	struct ibm_struct *ibm = data;
-	int len;
-
-	if (!ibm || !ibm->read)
-		return -EINVAL;
-
-	len = ibm->read(page);
-	if (len < 0)
-		return len;
-
-	if (len <= off + count)
-		*eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len > count)
-		len = count;
-	if (len < 0)
-		len = 0;
-
-	return len;
-}
-
-static int dispatch_write(struct file *file, const char __user * userbuf,
-			  unsigned long count, void *data)
-{
-	struct ibm_struct *ibm = data;
-	char *kernbuf;
-	int ret;
-
-	if (!ibm || !ibm->write)
-		return -EINVAL;
-
-	kernbuf = kmalloc(count + 2, GFP_KERNEL);
-	if (!kernbuf)
-		return -ENOMEM;
-
-	if (copy_from_user(kernbuf, userbuf, count)) {
-		kfree(kernbuf);
-		return -EFAULT;
-	}
-
-	kernbuf[count] = 0;
-	strcat(kernbuf, ",");
-	ret = ibm->write(kernbuf);
-	if (ret == 0)
-		ret = count;
-
-	kfree(kernbuf);
-
-	return ret;
-}
-
-static void dispatch_notify(acpi_handle handle, u32 event, void *data)
-{
-	struct ibm_struct *ibm = data;
-
-	if (!ibm || !ibm->notify)
-		return;
-
-	ibm->notify(ibm, event);
-}
-
-static int __init setup_notify(struct ibm_struct *ibm)
-{
-	acpi_status status;
-	int ret;
-
-	if (!*ibm->handle)
-		return 0;
-
-	ret = acpi_bus_get_device(*ibm->handle, &ibm->device);
-	if (ret < 0) {
-		printk(IBM_ERR "%s device not present\n", ibm->name);
-		return -ENODEV;
-	}
-
-	acpi_driver_data(ibm->device) = ibm;
-	sprintf(acpi_device_class(ibm->device), "%s/%s", IBM_NAME, ibm->name);
-
-	status = acpi_install_notify_handler(*ibm->handle, ibm->type,
-					     dispatch_notify, ibm);
-	if (ACPI_FAILURE(status)) {
-		if (status == AE_ALREADY_EXISTS) {
-			printk(IBM_NOTICE "another device driver is already handling %s events\n",
-				ibm->name);
-		} else {
-			printk(IBM_ERR "acpi_install_notify_handler(%s) failed: %d\n",
-				ibm->name, status);
-		}
-		return -ENODEV;
-	}
-	ibm->notify_installed = 1;
-	return 0;
-}
-
-static int __init ibm_device_add(struct acpi_device *device)
-{
-	return 0;
-}
-
-static int __init register_ibmacpi_subdriver(struct ibm_struct *ibm)
-{
-	int ret;
-
-	ibm->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL);
-	if (!ibm->driver) {
-		printk(IBM_ERR "kmalloc(ibm->driver) failed\n");
-		return -1;
-	}
-
-	sprintf(ibm->driver->name, "%s_%s", IBM_NAME, ibm->name);
-	ibm->driver->ids = ibm->hid;
-	ibm->driver->ops.add = &ibm_device_add;
-
-	ret = acpi_bus_register_driver(ibm->driver);
-	if (ret < 0) {
-		printk(IBM_ERR "acpi_bus_register_driver(%s) failed: %d\n",
-		       ibm->hid, ret);
-		kfree(ibm->driver);
-	}
-
-	return ret;
-}
+/*
+ * Module and infrastructure proble, init and exit handling
+ */
 
 static int __init ibm_init(struct ibm_struct *ibm)
 {
@@ -2500,27 +2629,35 @@ static void ibm_exit(struct ibm_struct *ibm)
 	}
 }
 
-static void __init ibm_handle_init(char *name,
-				   acpi_handle * handle, acpi_handle parent,
-				   char **paths, int num_paths, char **path)
+/* Probing */
+
+static char *ibm_thinkpad_ec_found = NULL;
+
+static char* __init check_dmi_for_ec(void)
 {
-	int i;
-	acpi_status status;
+	struct dmi_device *dev = NULL;
+	char ec_fw_string[18];
 
-	for (i = 0; i < num_paths; i++) {
-		status = acpi_get_handle(parent, paths[i], handle);
-		if (ACPI_SUCCESS(status)) {
-			*path = paths[i];
-			return;
+	/*
+	 * ThinkPad T23 or newer, A31 or newer, R50e or newer,
+	 * X32 or newer, all Z series;  Some models must have an
+	 * up-to-date BIOS or they will not be detected.
+	 *
+	 * See http://thinkwiki.org/wiki/List_of_DMI_IDs
+	 */
+	while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
+		if (sscanf(dev->name,
+			   "IBM ThinkPad Embedded Controller -[%17c",
+			   ec_fw_string) == 1) {
+			ec_fw_string[sizeof(ec_fw_string) - 1] = 0;
+			ec_fw_string[strcspn(ec_fw_string, " ]")] = 0;
+			return kstrdup(ec_fw_string, GFP_KERNEL);
 		}
 	}
-
-	*handle = NULL;
+	return NULL;
 }
 
-#define IBM_HANDLE_INIT(object)						\
-	ibm_handle_init(#object, &object##_handle, *object##_parent,	\
-		object##_paths, ARRAY_SIZE(object##_paths), &object##_path)
+/* Module init, exit, parameters */
 
 static int __init set_ibm_param(const char *val, struct kernel_param *kp)
 {
@@ -2538,6 +2675,9 @@ static int __init set_ibm_param(const char *val, struct kernel_param *kp)
 	return -EINVAL;
 }
 
+static int experimental;
+module_param(experimental, int, 0);
+
 #define IBM_PARAM(feature) \
 	module_param_call(feature, set_ibm_param, NULL, NULL, 0)
 
@@ -2559,44 +2699,6 @@ IBM_PARAM(brightness);
 IBM_PARAM(volume);
 IBM_PARAM(fan);
 
-static void acpi_ibm_exit(void)
-{
-	int i;
-
-	for (i = ARRAY_SIZE(ibms) - 1; i >= 0; i--)
-		ibm_exit(&ibms[i]);
-
-	if (proc_dir)
-		remove_proc_entry(IBM_DIR, acpi_root_dir);
-
-	if (ibm_thinkpad_ec_found)
-		kfree(ibm_thinkpad_ec_found);
-}
-
-static char* __init check_dmi_for_ec(void)
-{
-	struct dmi_device *dev = NULL;
-	char ec_fw_string[18];
-
-	/*
-	 * ThinkPad T23 or newer, A31 or newer, R50e or newer,
-	 * X32 or newer, all Z series;  Some models must have an
-	 * up-to-date BIOS or they will not be detected.
-	 *
-	 * See http://thinkwiki.org/wiki/List_of_DMI_IDs
-	 */
-	while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
-		if (sscanf(dev->name,
-			   "IBM ThinkPad Embedded Controller -[%17c",
-			   ec_fw_string) == 1) {
-			ec_fw_string[sizeof(ec_fw_string) - 1] = 0;
-			ec_fw_string[strcspn(ec_fw_string, " ]")] = 0;
-			return kstrdup(ec_fw_string, GFP_KERNEL);
-		}
-	}
-	return NULL;
-}
-
 static int __init acpi_ibm_init(void)
 {
 	int ret, i;
@@ -2662,5 +2764,19 @@ static int __init acpi_ibm_init(void)
 	return 0;
 }
 
+static void acpi_ibm_exit(void)
+{
+	int i;
+
+	for (i = ARRAY_SIZE(ibms) - 1; i >= 0; i--)
+		ibm_exit(&ibms[i]);
+
+	if (proc_dir)
+		remove_proc_entry(IBM_DIR, acpi_root_dir);
+
+	if (ibm_thinkpad_ec_found)
+		kfree(ibm_thinkpad_ec_found);
+}
+
 module_init(acpi_ibm_init);
 module_exit(acpi_ibm_exit);
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 028/105] ACPI: ibm-acpi: update copyright notice
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Update copyright and license info on the source code comments.  No
functional changes.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/ibm_acpi.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 984ec81..ae03b8f 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -3,7 +3,7 @@
  *
  *
  *  Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>
- *  Copyright (C) 2006 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+ *  Copyright (C) 2006-2007 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
  *
  *  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
@@ -17,7 +17,8 @@
  *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ *  02110-1301, USA.
  */
 
 #define IBM_VERSION "0.13"
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 029/105] ACPI: ibm-acpi: update documentation
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Update documentation header, and relocate a hunk of text that was missplaced.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 Documentation/ibm-acpi.txt |   85 +++++++++++++-------------------------------
 1 files changed, 25 insertions(+), 60 deletions(-)

diff --git a/Documentation/ibm-acpi.txt b/Documentation/ibm-acpi.txt
index cdcef01..f409f4b 100644
--- a/Documentation/ibm-acpi.txt
+++ b/Documentation/ibm-acpi.txt
@@ -1,16 +1,17 @@
 		    IBM ThinkPad ACPI Extras Driver
 
-                            Version 0.12
-                           17 August 2005
+                            Version 0.13
+                           31 December 2006
 
                Borislav Deianov <borislav@users.sf.net>
+	     Henrique de Moraes Holschuh <hmh@hmh.eng.br>
 		      http://ibm-acpi.sf.net/
 
 
 This is a Linux ACPI driver for the IBM ThinkPad laptops. It supports
 various features of these laptops which are accessible through the
-ACPI framework but not otherwise supported by the generic Linux ACPI
-drivers.
+ACPI framework but not otherwise fully supported by the generic Linux
+ACPI drivers.
 
 
 Status
@@ -638,6 +639,26 @@ The ThinkPad's ACPI DSDT code will reprogram the fan on its own when
 certain conditions are met.  It will override any fan programming done
 through ibm-acpi.
 
+The ibm-acpi kernel driver can be programmed to revert the fan level
+to a safe setting if userspace does not issue one of the fan commands:
+"enable", "disable", "level" or "watchdog" within a configurable
+ammount of time.  To do this, use the "watchdog" command.
+
+	echo 'watchdog <interval>' > /proc/acpi/ibm/fan
+
+Interval is the ammount of time in seconds to wait for one of the
+above mentioned fan commands before reseting the fan level to a safe
+one.  If set to zero, the watchdog is disabled (default).  When the
+watchdog timer runs out, it does the exact equivalent of the "enable"
+fan command.
+
+Note that the watchdog timer stops after it enables the fan.  It will
+be rearmed again automatically (using the same interval) when one of
+the above mentioned fan commands is received.  The fan watchdog is,
+therefore, not suitable to protect against fan mode changes made
+through means other than the "enable", "disable", and "level" fan
+commands.
+
 EXPERIMENTAL: WAN -- /proc/acpi/ibm/wan
 ---------------------------------------
 
@@ -670,59 +691,3 @@ example:
 
 	modprobe ibm_acpi hotkey=enable,0xffff video=auto_disable
 
-The ibm-acpi kernel driver can be programmed to revert the fan level
-to a safe setting if userspace does not issue one of the fan commands:
-"enable", "disable", "level" or "watchdog" within a configurable
-ammount of time.  To do this, use the "watchdog" command.
-
-	echo 'watchdog <interval>' > /proc/acpi/ibm/fan
-
-Interval is the ammount of time in seconds to wait for one of the
-above mentioned fan commands before reseting the fan level to a safe
-one.  If set to zero, the watchdog is disabled (default).  When the
-watchdog timer runs out, it does the exact equivalent of the "enable"
-fan command.
-
-Note that the watchdog timer stops after it enables the fan.  It will
-be rearmed again automatically (using the same interval) when one of
-the above mentioned fan commands is received.  The fan watchdog is,
-therefore, not suitable to protect against fan mode changes made
-through means other than the "enable", "disable", and "level" fan
-commands.
-
-
-Example Configuration
----------------------
-
-The ACPI support in the kernel is intended to be used in conjunction
-with a user-space daemon, acpid. The configuration files for this
-daemon control what actions are taken in response to various ACPI
-events. An example set of configuration files are included in the
-config/ directory of the tarball package available on the web
-site. Note that these are provided for illustration purposes only and
-may need to be adapted to your particular setup.
-
-The following utility scripts are used by the example action
-scripts (included with ibm-acpi for completeness):
-
-	/usr/local/sbin/idectl -- from the hdparm source distribution,
-		see http://www.ibiblio.org/pub/Linux/system/hardware
-	/usr/local/sbin/laptop_mode -- from the Linux kernel source
-		distribution, see Documentation/laptop-mode.txt
-	/sbin/service -- comes with Redhat/Fedora distributions
-	/usr/sbin/hibernate -- from the Software Suspend 2 distribution,
-		see http://softwaresuspend.berlios.de/
-
-Toan T Nguyen <ntt@physics.ucla.edu> notes that Suse uses the
-powersave program to suspend ('powersave --suspend-to-ram') or
-hibernate ('powersave --suspend-to-disk'). This means that the
-hibernate script is not needed on that distribution.
-
-Henrik Brix Andersen <brix@gentoo.org> has written a Gentoo ACPI event
-handler script for the X31. You can get the latest version from
-http://dev.gentoo.org/~brix/files/x31.sh
-
-David Schweikert <dws@ee.eth.ch> has written an alternative blank.sh
-script which works on Debian systems. This scripts has now been
-extended to also work on Fedora systems and included as the default
-blank.sh in the distribution.
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 031/105] ACPI: dock: use NULL for pointer
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Randy Dunlap, Andrew Morton, Len Brown

From: Randy Dunlap <randy.dunlap@oracle.com>

Use NULL instead of 0 for pointers:
drivers/acpi/dock.c:677:75: warning: Using plain integer as NULL pointer

Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/dock.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 811b1aa..4546bf8 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -29,6 +29,7 @@
 #include <linux/notifier.h>
 #include <linux/platform_device.h>
 #include <linux/jiffies.h>
+#include <linux/stddef.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
@@ -674,7 +675,7 @@ static ssize_t show_dock_uid(struct device *dev,
 			     struct device_attribute *attr, char *buf)
 {
 	unsigned long lbuf;
-	acpi_status status = acpi_evaluate_integer(dock_station->handle, "_UID", 0, &lbuf);
+	acpi_status status = acpi_evaluate_integer(dock_station->handle, "_UID", NULL, &lbuf);
 	if(ACPI_FAILURE(status)) {
 	    return 0;
 	}
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 033/105] ACPI: thinkpad-acpi: cleanup Kconfig for thinkpad-acpi
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Since ibm-acpi was renamed to thinkpad-acpi, rename and update its Kconfig
entries and Kconfig-related symbols accordingly.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/Kconfig         |   37 ++++++++++++++++++++-----------------
 drivers/misc/Makefile        |    2 +-
 drivers/misc/thinkpad_acpi.c |   26 +++++++++++++-------------
 drivers/misc/thinkpad_acpi.h |    8 ++++----
 4 files changed, 38 insertions(+), 35 deletions(-)

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 5d2bcbf..2cd96a3 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -122,40 +122,43 @@ config SONY_LAPTOP
 
 	  Read <file:Documentation/sony-laptop.txt> for more information.
 
-config ACPI_IBM
-	tristate "IBM ThinkPad Laptop Extras"
+config THINKPAD_ACPI
+	tristate "ThinkPad ACPI Laptop Extras"
 	depends on X86 && ACPI
 	select BACKLIGHT_CLASS_DEVICE
 	---help---
-	  This is a Linux ACPI driver for the IBM ThinkPad laptops. It adds
+	  This is a driver for the IBM and Lenovo ThinkPad laptops. It adds
 	  support for Fn-Fx key combinations, Bluetooth control, video
 	  output switching, ThinkLight control, UltraBay eject and more.
-	  For more information about this driver see <file:Documentation/ibm-acpi.txt>
-	  and <http://ibm-acpi.sf.net/> .
+	  For more information about this driver see 
+	  <file:Documentation/thinkpad-acpi.txt> and <http://ibm-acpi.sf.net/> .
 
-	  If you have an IBM ThinkPad laptop, say Y or M here.
+	  This driver was formely known as ibm-acpi.
 
-config ACPI_IBM_DOCK
+	  If you have an IBM or Lenovo ThinkPad laptop, say Y or M here.
+
+config THINKPAD_ACPI_DOCK
 	bool "Legacy Docking Station Support"
-	depends on ACPI_IBM
+	depends on THINKPAD_ACPI
 	depends on ACPI_DOCK=n
 	default n
 	---help---
-	  Allows the ibm_acpi driver to handle docking station events.
-	  This support is obsoleted by CONFIG_HOTPLUG_PCI_ACPI.  It will
-	  allow locking and removing the laptop from the docking station,
-	  but will not properly connect PCI devices.
+	  Allows the thinkpad_acpi driver to handle docking station events.
+	  This support was made obsolete by the generic ACPI docking station
+	  support (CONFIG_ACPI_DOCK).  It will allow locking and removing the
+	  laptop from the docking station, but will not properly connect PCI
+	  devices.
 
 	  If you are not sure, say N here.
 
-config ACPI_IBM_BAY
+config THINKPAD_ACPI_BAY
 	bool "Legacy Removable Bay Support"
-	depends on ACPI_IBM
+	depends on THINKPAD_ACPI
 	default y
 	---help---
-	  Allows the ibm_acpi driver to handle removable bays.  It will allow
-	  disabling the device in the bay, and also generate notifications when
-	  the bay lever is ejected or inserted.
+	  Allows the thinkpad_acpi driver to handle removable bays.  It will
+	  eletrically disable the device in the bay, and also generate
+	  notifications when the bay lever is ejected or inserted.
 
 	  If you are not sure, say Y here.
 
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index ebf4ff2..e325164 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -12,4 +12,4 @@ obj-$(CONFIG_TIFM_CORE)       	+= tifm_core.o
 obj-$(CONFIG_TIFM_7XX1)       	+= tifm_7xx1.o
 obj-$(CONFIG_SGI_IOC4)		+= ioc4.o
 obj-$(CONFIG_SONY_LAPTOP)	+= sony-laptop.o
-obj-$(CONFIG_ACPI_IBM)		+= thinkpad_acpi.o
+obj-$(CONFIG_THINKPAD_ACPI)	+= thinkpad_acpi.o
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 2836516..bb789db 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -1040,7 +1040,7 @@ static int light_write(char *buf)
 /* don't list other alternatives as we install a notify handler on the 570 */
 IBM_HANDLE(pci, root, "\\_SB.PCI");	/* 570 */
 
-#ifdef CONFIG_ACPI_IBM_DOCK
+#ifdef CONFIG_THINKPAD_ACPI_DOCK
 
 IBM_HANDLE(dock, root, "\\_SB.GDCK",	/* X30, X31, X40 */
 	   "\\_SB.PCI0.DOCK",	/* 600e/x,770e,770x,A2xm/p,T20-22,X20-21 */
@@ -1111,13 +1111,13 @@ static int dock_write(char *buf)
 	return 0;
 }
 
-#endif /* CONFIG_ACPI_IBM_DOCK */
+#endif /* CONFIG_THINKPAD_ACPI_DOCK */
 
 /*************************************************************************
  * Bay subdriver
  */
 
-#ifdef CONFIG_ACPI_IBM_BAY
+#ifdef CONFIG_THINKPAD_ACPI_BAY
 static int bay_status_supported;
 static int bay_status2_supported;
 static int bay_eject_supported;
@@ -1208,7 +1208,7 @@ static int bay_write(char *buf)
 
 	return 0;
 }
-#endif /* CONFIG_ACPI_IBM_BAY */
+#endif /* CONFIG_THINKPAD_ACPI_BAY */
 
 /*************************************************************************
  * CMOS subdriver
@@ -2477,7 +2477,7 @@ static struct ibm_struct ibms[] = {
 	 .read = light_read,
 	 .write = light_write,
 	 },
-#ifdef CONFIG_ACPI_IBM_DOCK
+#ifdef CONFIG_THINKPAD_ACPI_DOCK
 	{
 	 .name = "dock",
 	 .read = dock_read,
@@ -2494,7 +2494,7 @@ static struct ibm_struct ibms[] = {
 	 .type = ACPI_SYSTEM_NOTIFY,
 	 },
 #endif
-#ifdef CONFIG_ACPI_IBM_BAY
+#ifdef CONFIG_THINKPAD_ACPI_BAY
 	{
 	 .name = "bay",
 	 .init = bay_init,
@@ -2504,7 +2504,7 @@ static struct ibm_struct ibms[] = {
 	 .handle = &bay_handle,
 	 .type = ACPI_SYSTEM_NOTIFY,
 	 },
-#endif /* CONFIG_ACPI_IBM_BAY */
+#endif /* CONFIG_THINKPAD_ACPI_BAY */
 	{
 	 .name = "cmos",
 	 .read = cmos_read,
@@ -2686,12 +2686,12 @@ IBM_PARAM(hotkey);
 IBM_PARAM(bluetooth);
 IBM_PARAM(video);
 IBM_PARAM(light);
-#ifdef CONFIG_ACPI_IBM_DOCK
+#ifdef CONFIG_THINKPAD_ACPI_DOCK
 IBM_PARAM(dock);
 #endif
-#ifdef CONFIG_ACPI_IBM_BAY
+#ifdef CONFIG_THINKPAD_ACPI_BAY
 IBM_PARAM(bay);
-#endif /* CONFIG_ACPI_IBM_BAY */
+#endif /* CONFIG_THINKPAD_ACPI_BAY */
 IBM_PARAM(cmos);
 IBM_PARAM(led);
 IBM_PARAM(beep);
@@ -2725,18 +2725,18 @@ static int __init acpi_ibm_init(void)
 	IBM_HANDLE_INIT(hkey);
 	IBM_HANDLE_INIT(lght);
 	IBM_HANDLE_INIT(cmos);
-#ifdef CONFIG_ACPI_IBM_DOCK
+#ifdef CONFIG_THINKPAD_ACPI_DOCK
 	IBM_HANDLE_INIT(dock);
 #endif
 	IBM_HANDLE_INIT(pci);
-#ifdef CONFIG_ACPI_IBM_BAY
+#ifdef CONFIG_THINKPAD_ACPI_BAY
 	IBM_HANDLE_INIT(bay);
 	if (bay_handle)
 		IBM_HANDLE_INIT(bay_ej);
 	IBM_HANDLE_INIT(bay2);
 	if (bay2_handle)
 		IBM_HANDLE_INIT(bay2_ej);
-#endif /* CONFIG_ACPI_IBM_BAY */
+#endif /* CONFIG_THINKPAD_ACPI_BAY */
 	IBM_HANDLE_INIT(beep);
 	IBM_HANDLE_INIT(ecrd);
 	IBM_HANDLE_INIT(ecwr);
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 7ebaaa4..ee1b93a 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -163,7 +163,7 @@ static int register_ibmacpi_subdriver(struct ibm_struct *ibm);
  * Bay subdriver
  */
 
-#ifdef CONFIG_ACPI_IBM_BAY
+#ifdef CONFIG_THINKPAD_ACPI_BAY
 static int bay_status_supported, bay_eject_supported;
 static int bay_status2_supported, bay_eject2_supported;
 
@@ -174,7 +174,7 @@ static int bay_init(void);
 static void bay_notify(struct ibm_struct *ibm, u32 event);
 static int bay_read(char *p);
 static int bay_write(char *buf);
-#endif /* CONFIG_ACPI_IBM_BAY */
+#endif /* CONFIG_THINKPAD_ACPI_BAY */
 
 
 /*
@@ -229,13 +229,13 @@ static int cmos_write(char *buf);
  */
 
 static acpi_handle pci_handle;
-#ifdef CONFIG_ACPI_IBM_DOCK
+#ifdef CONFIG_THINKPAD_ACPI_DOCK
 static acpi_handle dock_handle;
 
 static void dock_notify(struct ibm_struct *ibm, u32 event);
 static int dock_read(char *p);
 static int dock_write(char *buf);
-#endif /* CONFIG_ACPI_IBM_DOCK */
+#endif /* CONFIG_THINKPAD_ACPI_DOCK */
 
 
 /*
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 034/105] ACPI: thinkpad-acpi: add compatibility MODULE_ALIAS entry
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Add a ibm_acpi module alias for userpace, so that modprobe ibm_acpi will
still load the correct driver.  This alias can be removed in the future,
probably two years from now if nothing warrants removing it sooner.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index bb789db..90ffc46 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -86,6 +86,9 @@ MODULE_DESCRIPTION(IBM_DESC);
 MODULE_VERSION(IBM_VERSION);
 MODULE_LICENSE("GPL");
 
+/* Please remove this in year 2009 */
+MODULE_ALIAS("ibm_acpi");
+
 #define __unused __attribute__ ((unused))
 
 /****************************************************************************
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 035/105] ACPI: thinkpad-acpi: cleanup after rename
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Cleanup documentation, driver strings and other misc stuff, now that the
driver is named "thinkpad-acpi".

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 Documentation/thinkpad-acpi.txt |   46 ++++++++++++++++++++++----------------
 drivers/misc/thinkpad_acpi.c    |   18 +++++++++------
 drivers/misc/thinkpad_acpi.h    |   21 +++++++++--------
 3 files changed, 49 insertions(+), 36 deletions(-)

diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt
index f409f4b..af18d29 100644
--- a/Documentation/thinkpad-acpi.txt
+++ b/Documentation/thinkpad-acpi.txt
@@ -1,17 +1,22 @@
-		    IBM ThinkPad ACPI Extras Driver
+		     ThinkPad ACPI Extras Driver
 
-                            Version 0.13
-                           31 December 2006
+                            Version 0.14
+                          March 26th, 2007
 
                Borislav Deianov <borislav@users.sf.net>
 	     Henrique de Moraes Holschuh <hmh@hmh.eng.br>
 		      http://ibm-acpi.sf.net/
 
 
-This is a Linux ACPI driver for the IBM ThinkPad laptops. It supports
-various features of these laptops which are accessible through the
-ACPI framework but not otherwise fully supported by the generic Linux
-ACPI drivers.
+This is a Linux driver for the IBM and Lenovo ThinkPad laptops. It
+supports various features of these laptops which are accessible
+through the ACPI and ACPI EC framework, but not otherwise fully
+supported by the generic Linux ACPI drivers.
+
+This driver used to be named ibm-acpi until kernel 2.6.21 and release
+0.13-20070314.  It used to be in the drivers/acpi tree, but it was
+moved to the drivers/misc tree and renamed to thinkpad-acpi for kernel
+2.6.22, and release 0.14.
 
 
 Status
@@ -43,6 +48,8 @@ Please include the following information in your report:
 
 	- ThinkPad model name
 	- a copy of your DSDT, from /proc/acpi/dsdt
+	- a copy of the output of dmidecode, with serial numbers
+	  and UUIDs masked off
 	- which driver features work and which don't
 	- the observed behavior of non-working features
 
@@ -53,8 +60,9 @@ Installation
 ------------
 
 If you are compiling this driver as included in the Linux kernel
-sources, simply enable the CONFIG_ACPI_IBM option (Power Management /
-ACPI / IBM ThinkPad Laptop Extras).
+sources, simply enable the CONFIG_THINKPAD_ACPI option, and optionally
+enable the CONFIG_THINKPAD_ACPI_BAY option if you want the
+thinkpad-specific bay functionality.
 
 Features
 --------
@@ -210,7 +218,7 @@ hot plugging of devices in the Linux ACPI framework. If the laptop was
 booted while not in the dock, the following message is shown in the
 logs:
 
-	Mar 17 01:42:34 aero kernel: ibm_acpi: dock device not present
+	Mar 17 01:42:34 aero kernel: thinkpad_acpi: dock device not present
 
 In this case, no dock-related events are generated but the dock and
 undock commands described below still work. They can be executed
@@ -270,7 +278,7 @@ This is due to the current lack of support for hot plugging of devices
 in the Linux ACPI framework. If the laptop was booted without the
 UltraBay, the following message is shown in the logs:
 
-	Mar 17 01:42:34 aero kernel: ibm_acpi: bay device not present
+	Mar 17 01:42:34 aero kernel: thinkpad_acpi: bay device not present
 
 In this case, no bay-related events are generated but the eject
 command described below still works. It can be executed manually or
@@ -637,12 +645,12 @@ range. The fan cannot be stopped or started with this command.
 
 The ThinkPad's ACPI DSDT code will reprogram the fan on its own when
 certain conditions are met.  It will override any fan programming done
-through ibm-acpi.
+through thinkpad-acpi.
 
-The ibm-acpi kernel driver can be programmed to revert the fan level
-to a safe setting if userspace does not issue one of the fan commands:
-"enable", "disable", "level" or "watchdog" within a configurable
-ammount of time.  To do this, use the "watchdog" command.
+The thinkpad-acpi kernel driver can be programmed to revert the fan
+level to a safe setting if userspace does not issue one of the fan
+commands: "enable", "disable", "level" or "watchdog" within a
+configurable ammount of time.  To do this, use the "watchdog" command.
 
 	echo 'watchdog <interval>' > /proc/acpi/ibm/fan
 
@@ -686,8 +694,8 @@ separating them with commas, for example:
 	echo enable,0xffff > /proc/acpi/ibm/hotkey
 	echo lcd_disable,crt_enable > /proc/acpi/ibm/video
 
-Commands can also be specified when loading the ibm_acpi module, for
-example:
+Commands can also be specified when loading the thinkpad-acpi module,
+for example:
 
-	modprobe ibm_acpi hotkey=enable,0xffff video=auto_disable
+	modprobe thinkpad_acpi hotkey=enable,0xffff video=auto_disable
 
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 90ffc46..ddaedf8 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -1,5 +1,5 @@
 /*
- *  ibm_acpi.c - IBM ThinkPad ACPI Extras
+ *  thinkpad_acpi.c - ThinkPad ACPI Extras
  *
  *
  *  Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>
@@ -21,10 +21,12 @@
  *  02110-1301, USA.
  */
 
-#define IBM_VERSION "0.13"
+#define IBM_VERSION "0.14"
 
 /*
  *  Changelog:
+ *  2007-03-27  0.14	renamed to thinkpad_acpi and moved to
+ *  			drivers/misc.
  *
  *  2006-11-22	0.13	new maintainer
  *  			changelog now lives in git commit history, and will
@@ -318,7 +320,9 @@ static int __init setup_notify(struct ibm_struct *ibm)
 	}
 
 	acpi_driver_data(ibm->device) = ibm;
-	sprintf(acpi_device_class(ibm->device), "%s/%s", IBM_NAME, ibm->name);
+	sprintf(acpi_device_class(ibm->device), "%s/%s",
+		IBM_ACPI_EVENT_PREFIX,
+		ibm->name);
 
 	status = acpi_install_notify_handler(*ibm->handle, ibm->type,
 					     dispatch_notify, ibm);
@@ -458,7 +462,7 @@ static char *next_cmd(char **cmds)
  * ibm-acpi init subdriver
  */
 
-static int ibm_acpi_driver_init(void)
+static int thinkpad_acpi_driver_init(void)
 {
 	printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION);
 	printk(IBM_INFO "%s\n", IBM_URL);
@@ -470,7 +474,7 @@ static int ibm_acpi_driver_init(void)
 	return 0;
 }
 
-static int ibm_acpi_driver_read(char *p)
+static int thinkpad_acpi_driver_read(char *p)
 {
 	int len = 0;
 
@@ -2440,8 +2444,8 @@ static struct proc_dir_entry *proc_dir = NULL;
 static struct ibm_struct ibms[] = {
 	{
 	 .name = "driver",
-	 .init = ibm_acpi_driver_init,
-	 .read = ibm_acpi_driver_read,
+	 .init = thinkpad_acpi_driver_init,
+	 .read = thinkpad_acpi_driver_read,
 	 },
 	{
 	 .name = "hotkey",
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index ee1b93a..015c02b 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -1,5 +1,5 @@
 /*
- *  ibm_acpi.h - IBM ThinkPad ACPI Extras
+ *  thinkpad_acpi.h - ThinkPad ACPI Extras
  *
  *
  *  Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>
@@ -21,8 +21,8 @@
  *  02110-1301, USA.
  */
 
-#ifndef __IBM_ACPI_H__
-#define __IBM_ACPI_H__
+#ifndef __THINKPAD_ACPI_H__
+#define __THINKPAD_ACPI_H__
 
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -47,12 +47,13 @@
  * Main driver
  */
 
-#define IBM_NAME "ibm"
-#define IBM_DESC "IBM ThinkPad ACPI Extras"
-#define IBM_FILE "ibm_acpi"
+#define IBM_NAME "thinkpad"
+#define IBM_DESC "ThinkPad ACPI Extras"
+#define IBM_FILE "thinkpad_acpi"
 #define IBM_URL "http://ibm-acpi.sf.net/"
 
-#define IBM_DIR IBM_NAME
+#define IBM_DIR "ibm"
+#define IBM_ACPI_EVENT_PREFIX "ibm"
 
 #define IBM_LOG IBM_FILE ": "
 #define IBM_ERR	   KERN_ERR    IBM_LOG
@@ -99,8 +100,8 @@ static void ibm_handle_init(char *name,
 
 /* procfs support */
 static struct proc_dir_entry *proc_dir;
-static int ibm_acpi_driver_init(void);
-static int ibm_acpi_driver_read(char *p);
+static int thinkpad_acpi_driver_init(void);
+static int thinkpad_acpi_driver_read(char *p);
 
 /* procfs helpers */
 static int dispatch_read(char *page, char **start, off_t off, int count,
@@ -434,4 +435,4 @@ static int wan_read(char *p);
 static int wan_write(char *buf);
 
 
-#endif /* __IBM_ACPI_H */
+#endif /* __THINKPAD_ACPI_H */
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 036/105] ACPI: thinkpad-acpi: update MAINTAINERS
@ 2007-04-29  4:50       ` Len Brown
       [not found]         ` <11778223411658-git-send-email-len.brown@intel.com>
  0 siblings, 1 reply; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Update MAINTAINERS file for the ibm-acpi -> thinkpad-acpi renaming.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 MAINTAINERS |   18 +++++++++---------
 1 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index dd6978b..7d42183 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1618,15 +1618,6 @@ W:	http://www.ia64-linux.org/
 T:	git kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git
 S:	Maintained
 
-IBM ACPI EXTRAS DRIVER
-P:	Henrique de Moraes Holschuh
-M:	ibm-acpi@hmh.eng.br
-L:	ibm-acpi-devel@lists.sourceforge.net
-W:	http://ibm-acpi.sourceforge.net
-W:	http://thinkwiki.org/wiki/Ibm-acpi
-T:	git repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git
-S:	Maintained
-
 SN-IA64 (Itanium) SUB-PLATFORM
 P:	Jes Sorensen
 M:	jes@sgi.com
@@ -3118,6 +3109,15 @@ P:	Chris Zankel
 M:	chris@zankel.net
 S:	Maintained
 
+THINKPAD ACPI EXTRAS DRIVER
+P:	Henrique de Moraes Holschuh
+M:	ibm-acpi@hmh.eng.br
+L:	ibm-acpi-devel@lists.sourceforge.net
+W:	http://ibm-acpi.sourceforge.net
+W:	http://thinkwiki.org/wiki/Ibm-acpi
+T:	git repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git
+S:	Maintained
+
 UltraSPARC (sparc64):
 P:	David S. Miller
 M:	davem@davemloft.net
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 046/105] ACPI: thinkpad-acpi: rename register_ibmacpi_subdriver
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Rename register_ibmacpi_subdriver to register_tpacpi_subdriver, as
we are not called ibmacpi anymore.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |    4 ++--
 drivers/misc/thinkpad_acpi.h |    2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index ddaedf8..cac73e5 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -345,7 +345,7 @@ static int __init ibm_device_add(struct acpi_device *device)
 	return 0;
 }
 
-static int __init register_ibmacpi_subdriver(struct ibm_struct *ibm)
+static int __init register_tpacpi_subdriver(struct ibm_struct *ibm)
 {
 	int ret;
 
@@ -2574,7 +2574,7 @@ static int __init ibm_init(struct ibm_struct *ibm)
 		return 0;
 
 	if (ibm->hid) {
-		ret = register_ibmacpi_subdriver(ibm);
+		ret = register_tpacpi_subdriver(ibm);
 		if (ret < 0)
 			return ret;
 		ibm->driver_registered = 1;
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 015c02b..b86e574 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -157,7 +157,7 @@ static void ibm_exit(struct ibm_struct *ibm);
 static void dispatch_notify(acpi_handle handle, u32 event, void *data);
 static int setup_notify(struct ibm_struct *ibm);
 static int ibm_device_add(struct acpi_device *device);
-static int register_ibmacpi_subdriver(struct ibm_struct *ibm);
+static int register_tpacpi_subdriver(struct ibm_struct *ibm);
 
 
 /*
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 047/105] ACPI: thinkpad-acpi: rename one stray use of ibm-acpi in a comment
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Rename a stray use of ibm-acpi on a comment, no functional changes.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index cac73e5..4b43486 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -459,7 +459,7 @@ static char *next_cmd(char **cmds)
  ****************************************************************************/
 
 /*************************************************************************
- * ibm-acpi init subdriver
+ * thinkpad-acpi init subdriver
  */
 
 static int thinkpad_acpi_driver_init(void)
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 048/105] ACPI: thinkpad-acpi: rename module glue
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Rename module init and exit functions, now that we are not called ibm-acpi
anymore.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |   12 ++++++------
 drivers/misc/thinkpad_acpi.h |    4 ++--
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 4b43486..80ef195 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -2707,7 +2707,7 @@ IBM_PARAM(brightness);
 IBM_PARAM(volume);
 IBM_PARAM(fan);
 
-static int __init acpi_ibm_init(void)
+static int __init thinkpad_acpi_module_init(void)
 {
 	int ret, i;
 
@@ -2754,7 +2754,7 @@ static int __init acpi_ibm_init(void)
 	proc_dir = proc_mkdir(IBM_DIR, acpi_root_dir);
 	if (!proc_dir) {
 		printk(IBM_ERR "unable to create proc dir %s", IBM_DIR);
-		acpi_ibm_exit();
+		thinkpad_acpi_module_exit();
 		return -ENODEV;
 	}
 	proc_dir->owner = THIS_MODULE;
@@ -2764,7 +2764,7 @@ static int __init acpi_ibm_init(void)
 		if (ret >= 0 && *ibms[i].param)
 			ret = ibms[i].write(ibms[i].param);
 		if (ret < 0) {
-			acpi_ibm_exit();
+			thinkpad_acpi_module_exit();
 			return ret;
 		}
 	}
@@ -2772,7 +2772,7 @@ static int __init acpi_ibm_init(void)
 	return 0;
 }
 
-static void acpi_ibm_exit(void)
+static void thinkpad_acpi_module_exit(void)
 {
 	int i;
 
@@ -2786,5 +2786,5 @@ static void acpi_ibm_exit(void)
 		kfree(ibm_thinkpad_ec_found);
 }
 
-module_init(acpi_ibm_init);
-module_exit(acpi_ibm_exit);
+module_init(thinkpad_acpi_module_init);
+module_exit(thinkpad_acpi_module_exit);
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index b86e574..8b2fd1a 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -115,8 +115,8 @@ static int experimental;
 static char *ibm_thinkpad_ec_found;
 
 static char* check_dmi_for_ec(void);
-static int acpi_ibm_init(void);
-static void acpi_ibm_exit(void);
+static int thinkpad_acpi_module_init(void);
+static void thinkpad_acpi_module_exit(void);
 
 
 /****************************************************************************
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 049/105] ACPI: thinkpad-acpi: rename thinkpad constants
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Rename all IBMACPI_ constants, now that we are not called ibm-acpi anymore.
Driver-specific constants are now prefixed TPACPI_, ThinkPad firmware
specific ones are now prefixed TP_CMOS_, TP_ACPI_, or TP_EC_.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |  188 +++++++++++++++++++++---------------------
 drivers/misc/thinkpad_acpi.h |   64 +++++++--------
 2 files changed, 125 insertions(+), 127 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 80ef195..1683bfe 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -781,16 +781,16 @@ static int video_init(void)
 
 	if (!vid_handle)
 		/* video switching not supported on R30, R31 */
-		video_supported = IBMACPI_VIDEO_NONE;
+		video_supported = TPACPI_VIDEO_NONE;
 	else if (acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd"))
 		/* 570 */
-		video_supported = IBMACPI_VIDEO_570;
+		video_supported = TPACPI_VIDEO_570;
 	else if (acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd"))
 		/* 600e/x, 770e, 770x */
-		video_supported = IBMACPI_VIDEO_770;
+		video_supported = TPACPI_VIDEO_770;
 	else
 		/* all others */
-		video_supported = IBMACPI_VIDEO_NEW;
+		video_supported = TPACPI_VIDEO_NEW;
 
 	return 0;
 }
@@ -805,15 +805,15 @@ static int video_status(void)
 	int status = 0;
 	int i;
 
-	if (video_supported == IBMACPI_VIDEO_570) {
+	if (video_supported == TPACPI_VIDEO_570) {
 		if (acpi_evalf(NULL, &i, "\\_SB.PHS", "dd", 0x87))
 			status = i & 3;
-	} else if (video_supported == IBMACPI_VIDEO_770) {
+	} else if (video_supported == TPACPI_VIDEO_770) {
 		if (acpi_evalf(NULL, &i, "\\VCDL", "d"))
 			status |= 0x01 * i;
 		if (acpi_evalf(NULL, &i, "\\VCDC", "d"))
 			status |= 0x02 * i;
-	} else if (video_supported == IBMACPI_VIDEO_NEW) {
+	} else if (video_supported == TPACPI_VIDEO_NEW) {
 		acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1);
 		if (acpi_evalf(NULL, &i, "\\VCDC", "d"))
 			status |= 0x02 * i;
@@ -832,10 +832,10 @@ static int video_autosw(void)
 {
 	int autosw = 0;
 
-	if (video_supported == IBMACPI_VIDEO_570)
+	if (video_supported == TPACPI_VIDEO_570)
 		acpi_evalf(vid_handle, &autosw, "SWIT", "d");
-	else if (video_supported == IBMACPI_VIDEO_770 ||
-		 video_supported == IBMACPI_VIDEO_NEW)
+	else if (video_supported == TPACPI_VIDEO_770 ||
+		 video_supported == TPACPI_VIDEO_NEW)
 		acpi_evalf(vid_handle, &autosw, "^VDEE", "d");
 
 	return autosw & 1;
@@ -848,7 +848,7 @@ static int video_switch(void)
 
 	if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1))
 		return -EIO;
-	ret = video_supported == IBMACPI_VIDEO_570 ?
+	ret = video_supported == TPACPI_VIDEO_570 ?
 	    acpi_evalf(ec_handle, NULL, "_Q16", "v") :
 	    acpi_evalf(vid_handle, NULL, "VSWT", "v");
 	acpi_evalf(vid_handle, NULL, "_DOS", "vd", autosw);
@@ -858,9 +858,9 @@ static int video_switch(void)
 
 static int video_expand(void)
 {
-	if (video_supported == IBMACPI_VIDEO_570)
+	if (video_supported == TPACPI_VIDEO_570)
 		return acpi_evalf(ec_handle, NULL, "_Q17", "v");
-	else if (video_supported == IBMACPI_VIDEO_770)
+	else if (video_supported == TPACPI_VIDEO_770)
 		return acpi_evalf(vid_handle, NULL, "VEXP", "v");
 	else
 		return acpi_evalf(NULL, NULL, "\\VEXP", "v");
@@ -870,10 +870,10 @@ static int video_switch2(int status)
 {
 	int ret;
 
-	if (video_supported == IBMACPI_VIDEO_570) {
+	if (video_supported == TPACPI_VIDEO_570) {
 		ret = acpi_evalf(NULL, NULL,
 				 "\\_SB.PHS2", "vdd", 0x8b, status | 0x80);
-	} else if (video_supported == IBMACPI_VIDEO_770) {
+	} else if (video_supported == TPACPI_VIDEO_770) {
 		int autosw = video_autosw();
 		if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1))
 			return -EIO;
@@ -904,12 +904,12 @@ static int video_read(char *p)
 	len += sprintf(p + len, "status:\t\tsupported\n");
 	len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0));
 	len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1));
-	if (video_supported == IBMACPI_VIDEO_NEW)
+	if (video_supported == TPACPI_VIDEO_NEW)
 		len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3));
 	len += sprintf(p + len, "auto:\t\t%s\n", enabled(autosw, 0));
 	len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable\n");
 	len += sprintf(p + len, "commands:\tcrt_enable, crt_disable\n");
-	if (video_supported == IBMACPI_VIDEO_NEW)
+	if (video_supported == TPACPI_VIDEO_NEW)
 		len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable\n");
 	len += sprintf(p + len, "commands:\tauto_enable, auto_disable\n");
 	len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n");
@@ -936,10 +936,10 @@ static int video_write(char *buf)
 			enable |= 0x02;
 		} else if (strlencmp(cmd, "crt_disable") == 0) {
 			disable |= 0x02;
-		} else if (video_supported == IBMACPI_VIDEO_NEW &&
+		} else if (video_supported == TPACPI_VIDEO_NEW &&
 			   strlencmp(cmd, "dvi_enable") == 0) {
 			enable |= 0x08;
-		} else if (video_supported == IBMACPI_VIDEO_NEW &&
+		} else if (video_supported == TPACPI_VIDEO_NEW &&
 			   strlencmp(cmd, "dvi_disable") == 0) {
 			disable |= 0x08;
 		} else if (strlencmp(cmd, "auto_enable") == 0) {
@@ -1283,16 +1283,16 @@ static int led_init(void)
 {
 	if (!led_handle)
 		/* led not supported on R30, R31 */
-		led_supported = IBMACPI_LED_NONE;
+		led_supported = TPACPI_LED_NONE;
 	else if (strlencmp(led_path, "SLED") == 0)
 		/* 570 */
-		led_supported = IBMACPI_LED_570;
+		led_supported = TPACPI_LED_570;
 	else if (strlencmp(led_path, "SYSL") == 0)
 		/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
-		led_supported = IBMACPI_LED_OLD;
+		led_supported = TPACPI_LED_OLD;
 	else
 		/* all others */
-		led_supported = IBMACPI_LED_NEW;
+		led_supported = TPACPI_LED_NEW;
 
 	return 0;
 }
@@ -1309,7 +1309,7 @@ static int led_read(char *p)
 	}
 	len += sprintf(p + len, "status:\t\tsupported\n");
 
-	if (led_supported == IBMACPI_LED_570) {
+	if (led_supported == TPACPI_LED_570) {
 		/* 570 */
 		int i, status;
 		for (i = 0; i < 8; i++) {
@@ -1354,23 +1354,23 @@ static int led_write(char *buf)
 		} else
 			return -EINVAL;
 
-		if (led_supported == IBMACPI_LED_570) {
+		if (led_supported == TPACPI_LED_570) {
 			/* 570 */
 			led = 1 << led;
 			if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
 					led, led_sled_arg1[ind]))
 				return -EIO;
-		} else if (led_supported == IBMACPI_LED_OLD) {
+		} else if (led_supported == TPACPI_LED_OLD) {
 			/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
 			led = 1 << led;
-			ret = ec_write(IBMACPI_LED_EC_HLMS, led);
+			ret = ec_write(TPACPI_LED_EC_HLMS, led);
 			if (ret >= 0)
 				ret =
-				    ec_write(IBMACPI_LED_EC_HLBL,
+				    ec_write(TPACPI_LED_EC_HLBL,
 				    	     led * led_exp_hlbl[ind]);
 			if (ret >= 0)
 				ret =
-				    ec_write(IBMACPI_LED_EC_HLCL,
+				    ec_write(TPACPI_LED_EC_HLCL,
 				    	     led * led_exp_hlcl[ind]);
 			if (ret < 0)
 				return ret;
@@ -1467,29 +1467,29 @@ static int thermal_init(void)
 				printk(IBM_ERR
 				       "ThinkPad ACPI EC access misbehaving, "
 				       "falling back to ACPI TMPx access mode\n");
-				thermal_read_mode = IBMACPI_THERMAL_ACPI_TMP07;
+				thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07;
 			} else {
 				printk(IBM_ERR
 				       "ThinkPad ACPI EC access misbehaving, "
 				       "disabling thermal sensors access\n");
-				thermal_read_mode = IBMACPI_THERMAL_NONE;
+				thermal_read_mode = TPACPI_THERMAL_NONE;
 			}
 		} else {
 			thermal_read_mode =
 			    (ta2 != 0) ?
-			    IBMACPI_THERMAL_TPEC_16 : IBMACPI_THERMAL_TPEC_8;
+			    TPACPI_THERMAL_TPEC_16 : TPACPI_THERMAL_TPEC_8;
 		}
 	} else if (acpi_tmp7) {
 		if (acpi_evalf(ec_handle, NULL, "UPDT", "qv")) {
 			/* 600e/x, 770e, 770x */
-			thermal_read_mode = IBMACPI_THERMAL_ACPI_UPDT;
+			thermal_read_mode = TPACPI_THERMAL_ACPI_UPDT;
 		} else {
 			/* Standard ACPI TMPx access, max 8 sensors */
-			thermal_read_mode = IBMACPI_THERMAL_ACPI_TMP07;
+			thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07;
 		}
 	} else {
 		/* temperatures not supported on 570, G4x, R30, R31, R32 */
-		thermal_read_mode = IBMACPI_THERMAL_NONE;
+		thermal_read_mode = TPACPI_THERMAL_NONE;
 	}
 
 	return 0;
@@ -1505,8 +1505,8 @@ static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s)
 		return -EINVAL;
 
 	switch (thermal_read_mode) {
-#if IBMACPI_MAX_THERMAL_SENSORS >= 16
-	case IBMACPI_THERMAL_TPEC_16:
+#if TPACPI_MAX_THERMAL_SENSORS >= 16
+	case TPACPI_THERMAL_TPEC_16:
 		for (i = 0; i < 8; i++) {
 			if (!acpi_ec_read(0xC0 + i, &tmp))
 				return -EIO;
@@ -1514,15 +1514,15 @@ static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s)
 		}
 		/* fallthrough */
 #endif
-	case IBMACPI_THERMAL_TPEC_8:
+	case TPACPI_THERMAL_TPEC_8:
 		for (i = 0; i < 8; i++) {
 			if (!acpi_ec_read(0x78 + i, &tmp))
 				return -EIO;
 			s->temp[i] = tmp * 1000;
 		}
-		return (thermal_read_mode == IBMACPI_THERMAL_TPEC_16) ? 16 : 8;
+		return (thermal_read_mode == TPACPI_THERMAL_TPEC_16) ? 16 : 8;
 
-	case IBMACPI_THERMAL_ACPI_UPDT:
+	case TPACPI_THERMAL_ACPI_UPDT:
 		if (!acpi_evalf(ec_handle, NULL, "UPDT", "v"))
 			return -EIO;
 		for (i = 0; i < 8; i++) {
@@ -1533,7 +1533,7 @@ static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s)
 		}
 		return 8;
 
-	case IBMACPI_THERMAL_ACPI_TMP07:
+	case TPACPI_THERMAL_ACPI_TMP07:
 		for (i = 0; i < 8; i++) {
 			tmpi[3] = '0' + i;
 			if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
@@ -1542,7 +1542,7 @@ static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s)
 		}
 		return 8;
 
-	case IBMACPI_THERMAL_NONE:
+	case TPACPI_THERMAL_NONE:
 	default:
 		return 0;
 	}
@@ -1848,18 +1848,18 @@ static int volume_write(char *buf)
 /*
  * FAN ACCESS MODES
  *
- * IBMACPI_FAN_RD_ACPI_GFAN:
+ * TPACPI_FAN_RD_ACPI_GFAN:
  * 	ACPI GFAN method: returns fan level
  *
- * 	see IBMACPI_FAN_WR_ACPI_SFAN
+ * 	see TPACPI_FAN_WR_ACPI_SFAN
  * 	EC 0x2f not available if GFAN exists
  *
- * IBMACPI_FAN_WR_ACPI_SFAN:
+ * TPACPI_FAN_WR_ACPI_SFAN:
  * 	ACPI SFAN method: sets fan level, 0 (stop) to 7 (max)
  *
  * 	EC 0x2f might be available *for reading*, but never for writing.
  *
- * IBMACPI_FAN_WR_TPEC:
+ * TPACPI_FAN_WR_TPEC:
  * 	ThinkPad EC register 0x2f (HFSP): fan control loop mode Supported
  * 	on almost all ThinkPads
  *
@@ -1888,7 +1888,7 @@ static int volume_write(char *buf)
  *			0x00 = stop
  * 			0x07 = max (set when temperatures critical)
  * 		Some ThinkPads may have other levels, see
- * 		IBMACPI_FAN_WR_ACPI_FANS (X31/X40/X41)
+ * 		TPACPI_FAN_WR_ACPI_FANS (X31/X40/X41)
  *
  *	FIRMWARE BUG: on some models, EC 0x2f might not be initialized at
  *	boot. Apparently the EC does not intialize it, so unless ACPI DSDT
@@ -1923,7 +1923,7 @@ static int volume_write(char *buf)
  *	For firmware bugs, refer to:
  *	http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues
  *
- * IBMACPI_FAN_WR_ACPI_FANS:
+ * TPACPI_FAN_WR_ACPI_FANS:
  *	ThinkPad X31, X40, X41.  Not available in the X60.
  *
  *	FANS ACPI handle: takes three arguments: low speed, medium speed,
@@ -1940,7 +1940,7 @@ static int volume_write(char *buf)
  * 	ACPI DSDT switches which set is in use depending on various
  * 	factors.
  *
- * 	IBMACPI_FAN_WR_TPEC is also available and should be used to
+ * 	TPACPI_FAN_WR_TPEC is also available and should be used to
  * 	command the fan.  The X31/X40/X41 seems to have 8 fan levels,
  * 	but the ACPI tables just mention level 7.
  */
@@ -1966,21 +1966,21 @@ IBM_HANDLE(sfan, ec, "SFAN",	/* 570 */
 
 static int fan_init(void)
 {
-	fan_status_access_mode = IBMACPI_FAN_NONE;
-	fan_control_access_mode = IBMACPI_FAN_WR_NONE;
+	fan_status_access_mode = TPACPI_FAN_NONE;
+	fan_control_access_mode = TPACPI_FAN_WR_NONE;
 	fan_control_commands = 0;
 	fan_control_status_known = 1;
 	fan_watchdog_maxinterval = 0;
 
 	if (gfan_handle) {
 		/* 570, 600e/x, 770e, 770x */
-		fan_status_access_mode = IBMACPI_FAN_RD_ACPI_GFAN;
+		fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN;
 	} else {
 		/* all other ThinkPads: note that even old-style
 		 * ThinkPad ECs supports the fan control register */
 		if (likely(acpi_ec_read(fan_status_offset,
 					&fan_control_initial_status))) {
-			fan_status_access_mode = IBMACPI_FAN_RD_TPEC;
+			fan_status_access_mode = TPACPI_FAN_RD_TPEC;
 
 			/* In some ThinkPads, neither the EC nor the ACPI
 			 * DSDT initialize the fan status, and it ends up
@@ -2015,9 +2015,9 @@ static int fan_init(void)
 
 	if (sfan_handle) {
 		/* 570, 770x-JL */
-		fan_control_access_mode = IBMACPI_FAN_WR_ACPI_SFAN;
+		fan_control_access_mode = TPACPI_FAN_WR_ACPI_SFAN;
 		fan_control_commands |=
-		    IBMACPI_FAN_CMD_LEVEL | IBMACPI_FAN_CMD_ENABLE;
+		    TPACPI_FAN_CMD_LEVEL | TPACPI_FAN_CMD_ENABLE;
 	} else {
 		if (!gfan_handle) {
 			/* gfan without sfan means no fan control */
@@ -2026,16 +2026,16 @@ static int fan_init(void)
 			if (fans_handle) {
 				/* X31, X40, X41 */
 				fan_control_access_mode =
-				    IBMACPI_FAN_WR_ACPI_FANS;
+				    TPACPI_FAN_WR_ACPI_FANS;
 				fan_control_commands |=
-				    IBMACPI_FAN_CMD_SPEED |
-				    IBMACPI_FAN_CMD_LEVEL |
-				    IBMACPI_FAN_CMD_ENABLE;
+				    TPACPI_FAN_CMD_SPEED |
+				    TPACPI_FAN_CMD_LEVEL |
+				    TPACPI_FAN_CMD_ENABLE;
 			} else {
-				fan_control_access_mode = IBMACPI_FAN_WR_TPEC;
+				fan_control_access_mode = TPACPI_FAN_WR_TPEC;
 				fan_control_commands |=
-				    IBMACPI_FAN_CMD_LEVEL |
-				    IBMACPI_FAN_CMD_ENABLE;
+				    TPACPI_FAN_CMD_LEVEL |
+				    TPACPI_FAN_CMD_ENABLE;
 			}
 		}
 	}
@@ -2048,10 +2048,10 @@ static int fan_get_status(u8 *status)
 	u8 s;
 
 	/* TODO:
-	 * Add IBMACPI_FAN_RD_ACPI_FANS ? */
+	 * Add TPACPI_FAN_RD_ACPI_FANS ? */
 
 	switch (fan_status_access_mode) {
-	case IBMACPI_FAN_RD_ACPI_GFAN:
+	case TPACPI_FAN_RD_ACPI_GFAN:
 		/* 570, 600e/x, 770e, 770x */
 
 		if (unlikely(!acpi_evalf(gfan_handle, &s, NULL, "d")))
@@ -2062,7 +2062,7 @@ static int fan_get_status(u8 *status)
 
 		break;
 
-	case IBMACPI_FAN_RD_TPEC:
+	case TPACPI_FAN_RD_TPEC:
 		/* all except 570, 600e/x, 770e, 770x */
 		if (unlikely(!acpi_ec_read(fan_status_offset, &s)))
 			return -EIO;
@@ -2090,7 +2090,7 @@ static int fan_get_speed(unsigned int *speed)
 	u8 hi, lo;
 
 	switch (fan_status_access_mode) {
-	case IBMACPI_FAN_RD_TPEC:
+	case TPACPI_FAN_RD_TPEC:
 		/* all except 570, 600e/x, 770e, 770x */
 		if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) ||
 			     !acpi_ec_read(fan_rpm_offset + 1, &hi)))
@@ -2140,7 +2140,7 @@ static void fan_watchdog_reset(void)
 static int fan_set_level(int level)
 {
 	switch (fan_control_access_mode) {
-	case IBMACPI_FAN_WR_ACPI_SFAN:
+	case TPACPI_FAN_WR_ACPI_SFAN:
 		if (level >= 0 && level <= 7) {
 			if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level))
 				return -EIO;
@@ -2148,10 +2148,10 @@ static int fan_set_level(int level)
 			return -EINVAL;
 		break;
 
-	case IBMACPI_FAN_WR_ACPI_FANS:
-	case IBMACPI_FAN_WR_TPEC:
-		if ((level != IBMACPI_FAN_EC_AUTO) &&
-		    (level != IBMACPI_FAN_EC_DISENGAGED) &&
+	case TPACPI_FAN_WR_ACPI_FANS:
+	case TPACPI_FAN_WR_TPEC:
+		if ((level != TP_EC_FAN_AUTO) &&
+		    (level != TP_EC_FAN_FULLSPEED) &&
 		    ((level < 0) || (level > 7)))
 			return -EINVAL;
 
@@ -2173,14 +2173,14 @@ static int fan_set_enable(void)
 	int rc;
 
 	switch (fan_control_access_mode) {
-	case IBMACPI_FAN_WR_ACPI_FANS:
-	case IBMACPI_FAN_WR_TPEC:
+	case TPACPI_FAN_WR_ACPI_FANS:
+	case TPACPI_FAN_WR_TPEC:
 		if ((rc = fan_get_status(&s)) < 0)
 			return rc;
 
 		/* Don't go out of emergency fan mode */
 		if (s != 7)
-			s = IBMACPI_FAN_EC_AUTO;
+			s = TP_EC_FAN_AUTO;
 
 		if (!acpi_ec_write(fan_status_offset, s))
 			return -EIO;
@@ -2188,7 +2188,7 @@ static int fan_set_enable(void)
 			fan_control_status_known = 1;
 		break;
 
-	case IBMACPI_FAN_WR_ACPI_SFAN:
+	case TPACPI_FAN_WR_ACPI_SFAN:
 		if ((rc = fan_get_status(&s)) < 0)
 			return rc;
 
@@ -2211,15 +2211,15 @@ static int fan_set_enable(void)
 static int fan_set_disable(void)
 {
 	switch (fan_control_access_mode) {
-	case IBMACPI_FAN_WR_ACPI_FANS:
-	case IBMACPI_FAN_WR_TPEC:
+	case TPACPI_FAN_WR_ACPI_FANS:
+	case TPACPI_FAN_WR_TPEC:
 		if (!acpi_ec_write(fan_status_offset, 0x00))
 			return -EIO;
 		else
 			fan_control_status_known = 1;
 		break;
 
-	case IBMACPI_FAN_WR_ACPI_SFAN:
+	case TPACPI_FAN_WR_ACPI_SFAN:
 		if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", 0x00))
 			return -EIO;
 		break;
@@ -2233,7 +2233,7 @@ static int fan_set_disable(void)
 static int fan_set_speed(int speed)
 {
 	switch (fan_control_access_mode) {
-	case IBMACPI_FAN_WR_ACPI_FANS:
+	case TPACPI_FAN_WR_ACPI_FANS:
 		if (speed >= 0 && speed <= 65535) {
 			if (!acpi_evalf(fans_handle, NULL, NULL, "vddd",
 					speed, speed, speed))
@@ -2256,7 +2256,7 @@ static int fan_read(char *p)
 	unsigned int speed = 0;
 
 	switch (fan_status_access_mode) {
-	case IBMACPI_FAN_RD_ACPI_GFAN:
+	case TPACPI_FAN_RD_ACPI_GFAN:
 		/* 570, 600e/x, 770e, 770x */
 		if ((rc = fan_get_status(&status)) < 0)
 			return rc;
@@ -2266,7 +2266,7 @@ static int fan_read(char *p)
 			       (status != 0) ? "enabled" : "disabled", status);
 		break;
 
-	case IBMACPI_FAN_RD_TPEC:
+	case TPACPI_FAN_RD_TPEC:
 		/* all except 570, 600e/x, 770e, 770x */
 		if ((rc = fan_get_status(&status)) < 0)
 			return rc;
@@ -2277,7 +2277,7 @@ static int fan_read(char *p)
 			else
 				/* Return most likely status. In fact, it
 				 * might be the only possible status */
-				status = IBMACPI_FAN_EC_AUTO;
+				status = TP_EC_FAN_AUTO;
 		}
 
 		len += sprintf(p + len, "status:\t\t%s\n",
@@ -2291,25 +2291,25 @@ static int fan_read(char *p)
 
 		len += sprintf(p + len, "speed:\t\t%d\n", speed);
 
-		if (status & IBMACPI_FAN_EC_DISENGAGED)
+		if (status & TP_EC_FAN_FULLSPEED)
 			/* Disengaged mode takes precedence */
 			len += sprintf(p + len, "level:\t\tdisengaged\n");
-		else if (status & IBMACPI_FAN_EC_AUTO)
+		else if (status & TP_EC_FAN_AUTO)
 			len += sprintf(p + len, "level:\t\tauto\n");
 		else
 			len += sprintf(p + len, "level:\t\t%d\n", status);
 		break;
 
-	case IBMACPI_FAN_NONE:
+	case TPACPI_FAN_NONE:
 	default:
 		len += sprintf(p + len, "status:\t\tnot supported\n");
 	}
 
-	if (fan_control_commands & IBMACPI_FAN_CMD_LEVEL) {
+	if (fan_control_commands & TPACPI_FAN_CMD_LEVEL) {
 		len += sprintf(p + len, "commands:\tlevel <level>");
 
 		switch (fan_control_access_mode) {
-		case IBMACPI_FAN_WR_ACPI_SFAN:
+		case TPACPI_FAN_WR_ACPI_SFAN:
 			len += sprintf(p + len, " (<level> is 0-7)\n");
 			break;
 
@@ -2320,12 +2320,12 @@ static int fan_read(char *p)
 		}
 	}
 
-	if (fan_control_commands & IBMACPI_FAN_CMD_ENABLE)
+	if (fan_control_commands & TPACPI_FAN_CMD_ENABLE)
 		len += sprintf(p + len, "commands:\tenable, disable\n"
 			       "commands:\twatchdog <timeout> (<timeout> is 0 (off), "
 			       "1-120 (seconds))\n");
 
-	if (fan_control_commands & IBMACPI_FAN_CMD_SPEED)
+	if (fan_control_commands & TPACPI_FAN_CMD_SPEED)
 		len += sprintf(p + len, "commands:\tspeed <speed>"
 			       " (<speed> is 0-65535)\n");
 
@@ -2337,9 +2337,9 @@ static int fan_write_cmd_level(const char *cmd, int *rc)
 	int level;
 
 	if (strlencmp(cmd, "level auto") == 0)
-		level = IBMACPI_FAN_EC_AUTO;
+		level = TP_EC_FAN_AUTO;
 	else if (strlencmp(cmd, "level disengaged") == 0)
-		level = IBMACPI_FAN_EC_DISENGAGED;
+		level = TP_EC_FAN_FULLSPEED;
 	else if (sscanf(cmd, "level %d", &level) != 1)
 		return 0;
 
@@ -2412,13 +2412,13 @@ static int fan_write(char *buf)
 	int rc = 0;
 
 	while (!rc && (cmd = next_cmd(&buf))) {
-		if (!((fan_control_commands & IBMACPI_FAN_CMD_LEVEL) &&
+		if (!((fan_control_commands & TPACPI_FAN_CMD_LEVEL) &&
 		      fan_write_cmd_level(cmd, &rc)) &&
-		    !((fan_control_commands & IBMACPI_FAN_CMD_ENABLE) &&
+		    !((fan_control_commands & TPACPI_FAN_CMD_ENABLE) &&
 		      (fan_write_cmd_enable(cmd, &rc) ||
 		       fan_write_cmd_disable(cmd, &rc) ||
 		       fan_write_cmd_watchdog(cmd, &rc))) &&
-		    !((fan_control_commands & IBMACPI_FAN_CMD_SPEED) &&
+		    !((fan_control_commands & TPACPI_FAN_CMD_SPEED) &&
 		      fan_write_cmd_speed(cmd, &rc))
 		    )
 			rc = -EINVAL;
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 8b2fd1a..02a297e 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -256,29 +256,27 @@ enum {					/* Fan control constants */
 	fan_rpm_offset = 0x84,		/* EC register 0x84: LSB, 0x85 MSB (RPM)
 					 * 0x84 must be read before 0x85 */
 
-	IBMACPI_FAN_EC_DISENGAGED 	= 0x40,	/* EC mode: tachometer
-						 * disengaged */
-	IBMACPI_FAN_EC_AUTO		= 0x80, /* EC mode: auto fan
-						 * control */
+	TP_EC_FAN_FULLSPEED = 0x40,	/* EC fan mode: full speed */
+	TP_EC_FAN_AUTO	    = 0x80,	/* EC fan mode: auto fan control */
 };
 
 enum fan_status_access_mode {
-	IBMACPI_FAN_NONE = 0,		/* No fan status or control */
-	IBMACPI_FAN_RD_ACPI_GFAN,	/* Use ACPI GFAN */
-	IBMACPI_FAN_RD_TPEC,		/* Use ACPI EC regs 0x2f, 0x84-0x85 */
+	TPACPI_FAN_NONE = 0,		/* No fan status or control */
+	TPACPI_FAN_RD_ACPI_GFAN,	/* Use ACPI GFAN */
+	TPACPI_FAN_RD_TPEC,		/* Use ACPI EC regs 0x2f, 0x84-0x85 */
 };
 
 enum fan_control_access_mode {
-	IBMACPI_FAN_WR_NONE = 0,	/* No fan control */
-	IBMACPI_FAN_WR_ACPI_SFAN,	/* Use ACPI SFAN */
-	IBMACPI_FAN_WR_TPEC,		/* Use ACPI EC reg 0x2f */
-	IBMACPI_FAN_WR_ACPI_FANS,	/* Use ACPI FANS and EC reg 0x2f */
+	TPACPI_FAN_WR_NONE = 0,		/* No fan control */
+	TPACPI_FAN_WR_ACPI_SFAN,	/* Use ACPI SFAN */
+	TPACPI_FAN_WR_TPEC,		/* Use ACPI EC reg 0x2f */
+	TPACPI_FAN_WR_ACPI_FANS,	/* Use ACPI FANS and EC reg 0x2f */
 };
 
 enum fan_control_commands {
-	IBMACPI_FAN_CMD_SPEED 	= 0x0001,	/* speed command */
-	IBMACPI_FAN_CMD_LEVEL 	= 0x0002,	/* level command  */
-	IBMACPI_FAN_CMD_ENABLE	= 0x0004,	/* enable/disable cmd,
+	TPACPI_FAN_CMD_SPEED 	= 0x0001,	/* speed command */
+	TPACPI_FAN_CMD_LEVEL 	= 0x0002,	/* level command  */
+	TPACPI_FAN_CMD_ENABLE	= 0x0004,	/* enable/disable cmd,
 						 * and also watchdog cmd */
 };
 
@@ -333,16 +331,16 @@ static int hotkey_write(char *buf);
  */
 
 enum led_access_mode {
-	IBMACPI_LED_NONE = 0,
-	IBMACPI_LED_570,	/* 570 */
-	IBMACPI_LED_OLD,	/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
-	IBMACPI_LED_NEW,	/* all others */
+	TPACPI_LED_NONE = 0,
+	TPACPI_LED_570,	/* 570 */
+	TPACPI_LED_OLD,	/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
+	TPACPI_LED_NEW,	/* all others */
 };
 
-enum {	/* For IBMACPI_LED_OLD */
-	IBMACPI_LED_EC_HLCL = 0x0c,	/* EC reg to get led to power on */
-	IBMACPI_LED_EC_HLBL = 0x0d,	/* EC reg to blink a lit led */
-	IBMACPI_LED_EC_HLMS = 0x0e,	/* EC reg to select led to command */
+enum {	/* For TPACPI_LED_OLD */
+	TPACPI_LED_EC_HLCL = 0x0c,	/* EC reg to get led to power on */
+	TPACPI_LED_EC_HLBL = 0x0d,	/* EC reg to blink a lit led */
+	TPACPI_LED_EC_HLMS = 0x0e,	/* EC reg to select led to command */
 };
 
 static enum led_access_mode led_supported;
@@ -370,16 +368,16 @@ static int light_write(char *buf);
  */
 
 enum thermal_access_mode {
-	IBMACPI_THERMAL_NONE = 0,	/* No thermal support */
-	IBMACPI_THERMAL_ACPI_TMP07,	/* Use ACPI TMP0-7 */
-	IBMACPI_THERMAL_ACPI_UPDT,	/* Use ACPI TMP0-7 with UPDT */
-	IBMACPI_THERMAL_TPEC_8,		/* Use ACPI EC regs, 8 sensors */
-	IBMACPI_THERMAL_TPEC_16,	/* Use ACPI EC regs, 16 sensors */
+	TPACPI_THERMAL_NONE = 0,	/* No thermal support */
+	TPACPI_THERMAL_ACPI_TMP07,	/* Use ACPI TMP0-7 */
+	TPACPI_THERMAL_ACPI_UPDT,	/* Use ACPI TMP0-7 with UPDT */
+	TPACPI_THERMAL_TPEC_8,		/* Use ACPI EC regs, 8 sensors */
+	TPACPI_THERMAL_TPEC_16,		/* Use ACPI EC regs, 16 sensors */
 };
 
-#define IBMACPI_MAX_THERMAL_SENSORS 16	/* Max thermal sensors supported */
+#define TPACPI_MAX_THERMAL_SENSORS 16	/* Max thermal sensors supported */
 struct ibm_thermal_sensors_struct {
-	s32 temp[IBMACPI_MAX_THERMAL_SENSORS];
+	s32 temp[TPACPI_MAX_THERMAL_SENSORS];
 };
 
 static int thermal_init(void);
@@ -392,10 +390,10 @@ static int thermal_read(char *p);
  */
 
 enum video_access_mode {
-	IBMACPI_VIDEO_NONE = 0,
-	IBMACPI_VIDEO_570,	/* 570 */
-	IBMACPI_VIDEO_770,	/* 600e/x, 770e, 770x */
-	IBMACPI_VIDEO_NEW,	/* all others */
+	TPACPI_VIDEO_NONE = 0,
+	TPACPI_VIDEO_570,	/* 570 */
+	TPACPI_VIDEO_770,	/* 600e/x, 770e, 770x */
+	TPACPI_VIDEO_NEW,	/* all others */
 };
 
 static enum video_access_mode video_supported;
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 050/105] ACPI: thinkpad-acpi: update fan firmware documentation
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Update some stuff in the in-code text describing the ThinkPad fan
firmware.  This patch has no code changes.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |   28 +++++++++++++---------------
 1 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 1683bfe..4131a78 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -1852,16 +1852,17 @@ static int volume_write(char *buf)
  * 	ACPI GFAN method: returns fan level
  *
  * 	see TPACPI_FAN_WR_ACPI_SFAN
- * 	EC 0x2f not available if GFAN exists
+ * 	EC 0x2f (HFSP) not available if GFAN exists
  *
  * TPACPI_FAN_WR_ACPI_SFAN:
  * 	ACPI SFAN method: sets fan level, 0 (stop) to 7 (max)
  *
- * 	EC 0x2f might be available *for reading*, but never for writing.
+ * 	EC 0x2f (HFSP) might be available *for reading*, but do not use
+ * 	it for writing.
  *
  * TPACPI_FAN_WR_TPEC:
- * 	ThinkPad EC register 0x2f (HFSP): fan control loop mode Supported
- * 	on almost all ThinkPads
+ * 	ThinkPad EC register 0x2f (HFSP): fan control loop mode
+ * 	Supported on almost all ThinkPads
  *
  * 	Fan speed changes of any sort (including those caused by the
  * 	disengaged mode) are usually done slowly by the firmware as the
@@ -1875,12 +1876,13 @@ static int volume_write(char *buf)
  *	 7	automatic mode engaged;
  *  		(default operation mode of the ThinkPad)
  * 		fan level is ignored in this mode.
- *	 6	disengage mode (takes precedence over bit 7);
+ *	 6	full speed mode (takes precedence over bit 7);
  *		not available on all thinkpads.  May disable
- *		the tachometer, and speeds up fan to 100% duty-cycle,
- *		which speeds it up far above the standard RPM
- *		levels.  It is not impossible that it could cause
- *		hardware damage.
+ *		the tachometer while the fan controller ramps up
+ *		the speed (which can take up to a few *minutes*).
+ *		Speeds up fan to 100% duty-cycle, which is far above
+ *		the standard RPM levels.  It is not impossible that
+ *		it could cause hardware damage.
  *	5-3	unused in some models.  Extra bits for fan level
  *		in others, but still useless as all values above
  *		7 map to the same speed as level 7 in these models.
@@ -1916,9 +1918,8 @@ static int volume_write(char *buf)
  *	FIRMWARE BUG: always read 0x84 first, otherwise incorrect readings
  *	might result.
  *
- *	FIRMWARE BUG: when EC 0x2f bit 6 is set (disengaged mode), this
- *	register is not invalidated in ThinkPads that disable tachometer
- *	readings.  Thus, the tachometer readings go stale.
+ *	FIRMWARE BUG: may go stale while the EC is switching to full speed
+ *	mode.
  *
  *	For firmware bugs, refer to:
  *	http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues
@@ -2283,9 +2284,6 @@ static int fan_read(char *p)
 		len += sprintf(p + len, "status:\t\t%s\n",
 			       (status != 0) ? "enabled" : "disabled");
 
-		/* No ThinkPad boots on disengaged mode, we can safely
-		 * assume the tachometer is online if fan control status
-		 * was unknown */
 		if ((rc = fan_get_speed(&speed)) < 0)
 			return rc;
 
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 051/105] ACPI: thinkpad-acpi: add debug mode
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Add a debug mode parameter and verbose debug mode Kconfig option.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 Documentation/thinkpad-acpi.txt |   13 +++++++++++++
 drivers/misc/Kconfig            |   10 ++++++++++
 drivers/misc/thinkpad_acpi.c    |    3 +++
 drivers/misc/thinkpad_acpi.h    |   13 +++++++++++++
 4 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt
index af18d29..82fd822 100644
--- a/Documentation/thinkpad-acpi.txt
+++ b/Documentation/thinkpad-acpi.txt
@@ -699,3 +699,16 @@ for example:
 
 	modprobe thinkpad_acpi hotkey=enable,0xffff video=auto_disable
 
+Enabling debugging output
+-------------------------
+
+The module takes a debug paramater which can be used to selectively
+enable various classes of debugging output, for example:
+
+	 modprobe ibm_acpi debug=0xffff
+
+will enable all debugging output classes.  It takes a bitmask, so
+to enable more than one output class, just add their values.
+
+There is also a kernel build option to enable more debugging
+information, which may be necessary to debug driver problems.
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 2cd96a3..44e4c8f 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -137,6 +137,16 @@ config THINKPAD_ACPI
 
 	  If you have an IBM or Lenovo ThinkPad laptop, say Y or M here.
 
+config THINKPAD_ACPI_DEBUG
+	bool "Verbose debug mode"
+	depends on THINKPAD_ACPI
+	default n
+	---help---
+	  Enables extra debugging information, at the expense of a slightly
+	  increase in driver size.
+
+	  If you are not sure, say N here.
+
 config THINKPAD_ACPI_DOCK
 	bool "Legacy Docking Station Support"
 	depends on THINKPAD_ACPI
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 4131a78..7fa906f 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -2684,6 +2684,9 @@ static int __init set_ibm_param(const char *val, struct kernel_param *kp)
 static int experimental;
 module_param(experimental, int, 0);
 
+static u32 dbg_level;
+module_param_named(debug, dbg_level, uint, 0);
+
 #define IBM_PARAM(feature) \
 	module_param_call(feature, set_ibm_param, NULL, NULL, 0)
 
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 02a297e..b2348d7 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -74,6 +74,18 @@
 #define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
 #define strlencmp(a,b) (strncmp((a), (b), strlen(b)))
 
+/* Debugging */
+#define TPACPI_DBG_ALL		0xffff
+#define dbg_printk(a_dbg_level, format, arg...) \
+	do { if (dbg_level & a_dbg_level) \
+		printk(IBM_DEBUG "%s: " format, __func__ , ## arg); } while (0)
+#ifdef CONFIG_THINKPAD_ACPI_DEBUG
+#define vdbg_printk(a_dbg_level, format, arg...) \
+	dbg_printk(a_dbg_level, format, ## arg)
+#else
+#define vdbg_printk(a_dbg_level, format, arg...)
+#endif
+
 /* ACPI HIDs */
 #define IBM_HKEY_HID    "IBM0068"
 #define IBM_PCI_HID     "PNP0A03"
@@ -112,6 +124,7 @@ static char *next_cmd(char **cmds);
 
 /* Module */
 static int experimental;
+static u32 dbg_level;
 static char *ibm_thinkpad_ec_found;
 
 static char* check_dmi_for_ec(void);
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 052/105] ACPI: thinkpad-acpi: clean up probing and move init to subdrivers
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Move most of the probing code to its own function, and most of the
subdriver-specific init code into subdriver init functions.

This allows us to not define pci_handle unless the dock subdriver is
enabled, as well.

This patch causes a minor userland interface change: if a subdriver doesn't
detect a capability, /proc entries for it are not created anymore (as
opposed to a /proc entry that just returned "unsupported").

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |  231 +++++++++++++++++++++++++++---------------
 drivers/misc/thinkpad_acpi.h |    4 +-
 2 files changed, 151 insertions(+), 84 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 7fa906f..eeab394 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -277,9 +277,9 @@ static int _sta(acpi_handle handle)
  * ACPI device model
  */
 
-static void __init ibm_handle_init(char *name,
-				   acpi_handle * handle, acpi_handle parent,
-				   char **paths, int num_paths, char **path)
+static void ibm_handle_init(char *name,
+			   acpi_handle *handle, acpi_handle parent,
+			   char **paths, int num_paths, char **path)
 {
 	int i;
 	acpi_status status;
@@ -351,8 +351,8 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm)
 
 	ibm->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL);
 	if (!ibm->driver) {
-		printk(IBM_ERR "kmalloc(ibm->driver) failed\n");
-		return -1;
+		printk(IBM_ERR "kzalloc(ibm->driver) failed\n");
+		return -ENOMEM;
 	}
 
 	sprintf(ibm->driver->name, "%s_%s", IBM_NAME, ibm->name);
@@ -364,7 +364,9 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm)
 		printk(IBM_ERR "acpi_bus_register_driver(%s) failed: %d\n",
 		       ibm->hid, ret);
 		kfree(ibm->driver);
-	}
+		ibm->driver = NULL;
+	} else if (!ret)
+		ibm->driver_registered = 1;
 
 	return ret;
 }
@@ -495,6 +497,8 @@ static int hotkey_orig_mask;
 
 static int hotkey_init(void)
 {
+	IBM_HANDLE_INIT(hkey);
+
 	/* hotkey not supported on 570 */
 	hotkey_supported = hkey_handle != NULL;
 
@@ -508,13 +512,14 @@ static int hotkey_init(void)
 			return -ENODEV;
 	}
 
-	return 0;
+	return (hotkey_supported)? 0 : 1;
 }
 
 static void hotkey_exit(void)
 {
-	if (hotkey_supported)
+	if (hotkey_supported) {
 		hotkey_set(hotkey_orig_status, hotkey_orig_mask);
+	}
 }
 
 static void hotkey_notify(struct ibm_struct *ibm, u32 event)
@@ -628,12 +633,14 @@ static int bluetooth_supported;
 
 static int bluetooth_init(void)
 {
+	IBM_HANDLE_INIT(hkey);
+
 	/* bluetooth not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
 	   G4x, R30, R31, R40e, R50e, T20-22, X20-21 */
 	bluetooth_supported = hkey_handle &&
 	    acpi_evalf(hkey_handle, NULL, "GBDC", "qv");
 
-	return 0;
+	return (bluetooth_supported)? 0 : 1;
 }
 
 static int bluetooth_status(void)
@@ -697,10 +704,12 @@ static int wan_supported;
 
 static int wan_init(void)
 {
+	IBM_HANDLE_INIT(hkey);
+
 	wan_supported = hkey_handle &&
 	    acpi_evalf(hkey_handle, NULL, "GWAN", "qv");
 
-	return 0;
+	return (wan_supported)? 0 : 1;
 }
 
 static int wan_status(void)
@@ -775,6 +784,9 @@ static int video_init(void)
 {
 	int ivga;
 
+	IBM_HANDLE_INIT(vid);
+	IBM_HANDLE_INIT(vid2);
+
 	if (vid2_handle && acpi_evalf(NULL, &ivga, "\\IVGA", "d") && ivga)
 		/* G41, assume IVGA doesn't change */
 		vid_handle = vid2_handle;
@@ -792,7 +804,7 @@ static int video_init(void)
 		/* all others */
 		video_supported = TPACPI_VIDEO_NEW;
 
-	return 0;
+	return (video_supported != TPACPI_VIDEO_NONE)? 0 : 1;
 }
 
 static void video_exit(void)
@@ -979,6 +991,10 @@ IBM_HANDLE(ledb, ec, "LEDB");		/* G4x */
 
 static int light_init(void)
 {
+	IBM_HANDLE_INIT(ledb);
+	IBM_HANDLE_INIT(lght);
+	IBM_HANDLE_INIT(cmos);
+
 	/* light not supported on 570, 600e/x, 770e, 770x, G4x, R30, R31 */
 	light_supported = (cmos_handle || lght_handle) && !ledb_handle;
 
@@ -988,7 +1004,7 @@ static int light_init(void)
 		light_status_supported = acpi_evalf(ec_handle, NULL,
 						    "KBLT", "qv");
 
-	return 0;
+	return (light_supported)? 0 : 1;
 }
 
 static int light_read(char *p)
@@ -1044,9 +1060,6 @@ static int light_write(char *buf)
  * Dock subdriver
  */
 
-/* don't list other alternatives as we install a notify handler on the 570 */
-IBM_HANDLE(pci, root, "\\_SB.PCI");	/* 570 */
-
 #ifdef CONFIG_THINKPAD_ACPI_DOCK
 
 IBM_HANDLE(dock, root, "\\_SB.GDCK",	/* X30, X31, X40 */
@@ -1055,8 +1068,19 @@ IBM_HANDLE(dock, root, "\\_SB.GDCK",	/* X30, X31, X40 */
 	   "\\_SB.PCI.ISA.SLCE",	/* 570 */
     );				/* A21e,G4x,R30,R31,R32,R40,R40e,R50e */
 
+/* don't list other alternatives as we install a notify handler on the 570 */
+IBM_HANDLE(pci, root, "\\_SB.PCI");	/* 570 */
+
 #define dock_docked() (_sta(dock_handle) & 1)
 
+static int dock_init(void)
+{
+	IBM_HANDLE_INIT(dock);
+	IBM_HANDLE_INIT(pci);
+
+	return (dock_handle)? 0 : 1;
+}
+
 static void dock_notify(struct ibm_struct *ibm, u32 event)
 {
 	int docked = dock_docked();
@@ -1147,6 +1171,13 @@ IBM_HANDLE(bay2_ej, bay2, "_EJ3",	/* 600e/x, 770e, A3x */
 
 static int bay_init(void)
 {
+	IBM_HANDLE_INIT(bay);
+	if (bay_handle)
+		IBM_HANDLE_INIT(bay_ej);
+	IBM_HANDLE_INIT(bay2);
+	if (bay2_handle)
+		IBM_HANDLE_INIT(bay2_ej);
+
 	bay_status_supported = bay_handle &&
 	    acpi_evalf(bay_handle, NULL, "_STA", "qv");
 	bay_status2_supported = bay2_handle &&
@@ -1157,7 +1188,8 @@ static int bay_init(void)
 	bay_eject2_supported = bay2_handle && bay2_ej_handle &&
 	    (strlencmp(bay2_ej_path, "_EJ0") == 0 || experimental);
 
-	return 0;
+	return (bay_status_supported || bay_eject_supported ||
+		bay_status2_supported || bay_eject2_supported)? 0 : 1;
 }
 
 static void bay_notify(struct ibm_struct *ibm, u32 event)
@@ -1221,6 +1253,13 @@ static int bay_write(char *buf)
  * CMOS subdriver
  */
 
+static int cmos_init(void)
+{
+	IBM_HANDLE_INIT(cmos);
+
+	return (cmos_handle)? 0 : 1;
+}
+
 static int cmos_eval(int cmos_cmd)
 {
 	if (cmos_handle)
@@ -1281,6 +1320,8 @@ IBM_HANDLE(led, ec, "SLED",	/* 570 */
 
 static int led_init(void)
 {
+	IBM_HANDLE_INIT(led);
+
 	if (!led_handle)
 		/* led not supported on R30, R31 */
 		led_supported = TPACPI_LED_NONE;
@@ -1294,7 +1335,7 @@ static int led_init(void)
 		/* all others */
 		led_supported = TPACPI_LED_NEW;
 
-	return 0;
+	return (led_supported != TPACPI_LED_NONE)? 0 : 1;
 }
 
 #define led_status(s) ((s) == 0 ? "off" : ((s) == 1 ? "on" : "blinking"))
@@ -1391,6 +1432,13 @@ static int led_write(char *buf)
 
 IBM_HANDLE(beep, ec, "BEEP");	/* all except R30, R31 */
 
+static int beep_init(void)
+{
+	IBM_HANDLE_INIT(beep);
+
+	return (beep_handle)? 0 : 1;
+}
+
 static int beep_read(char *p)
 {
 	int len = 0;
@@ -1436,7 +1484,9 @@ static int thermal_init(void)
 {
 	u8 t, ta1, ta2;
 	int i;
-	int acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv");
+	int acpi_tmp7;
+
+	acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv");
 
 	if (ibm_thinkpad_ec_found && experimental) {
 		/*
@@ -1492,7 +1542,7 @@ static int thermal_init(void)
 		thermal_read_mode = TPACPI_THERMAL_NONE;
 	}
 
-	return 0;
+	return (thermal_read_mode != TPACPI_THERMAL_NONE)? 0 : 1;
 }
 
 static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s)
@@ -1973,6 +2023,10 @@ static int fan_init(void)
 	fan_control_status_known = 1;
 	fan_watchdog_maxinterval = 0;
 
+	IBM_HANDLE_INIT(fans);
+	IBM_HANDLE_INIT(gfan);
+	IBM_HANDLE_INIT(sfan);
+
 	if (gfan_handle) {
 		/* 570, 600e/x, 770e, 770x */
 		fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN;
@@ -2010,7 +2064,7 @@ static int fan_init(void)
 			printk(IBM_ERR
 			       "ThinkPad ACPI EC access misbehaving, "
 			       "fan status and control unavailable\n");
-			return 0;
+			return 1;
 		}
 	}
 
@@ -2041,7 +2095,9 @@ static int fan_init(void)
 		}
 	}
 
-	return 0;
+	return (fan_status_access_mode != TPACPI_FAN_NONE ||
+	        fan_control_access_mode != TPACPI_FAN_WR_NONE)?
+			0 : 1;
 }
 
 static int fan_get_status(u8 *status)
@@ -2485,6 +2541,7 @@ static struct ibm_struct ibms[] = {
 #ifdef CONFIG_THINKPAD_ACPI_DOCK
 	{
 	 .name = "dock",
+	 .init = dock_init,
 	 .read = dock_read,
 	 .write = dock_write,
 	 .notify = dock_notify,
@@ -2512,6 +2569,7 @@ static struct ibm_struct ibms[] = {
 #endif /* CONFIG_THINKPAD_ACPI_BAY */
 	{
 	 .name = "cmos",
+	 .init = cmos_init,
 	 .read = cmos_read,
 	 .write = cmos_write,
 	 },
@@ -2523,6 +2581,7 @@ static struct ibm_struct ibms[] = {
 	 },
 	{
 	 .name = "beep",
+	 .init = beep_init,
 	 .read = beep_read,
 	 .write = beep_write,
 	 },
@@ -2571,20 +2630,33 @@ static int __init ibm_init(struct ibm_struct *ibm)
 	if (ibm->experimental && !experimental)
 		return 0;
 
-	if (ibm->hid) {
-		ret = register_tpacpi_subdriver(ibm);
-		if (ret < 0)
-			return ret;
-		ibm->driver_registered = 1;
-	}
-
 	if (ibm->init) {
 		ret = ibm->init();
-		if (ret != 0)
+		if (ret > 0)
+			return 0;	/* probe failed */
+		if (ret)
 			return ret;
 		ibm->init_called = 1;
 	}
 
+	if (ibm->hid) {
+		ret = register_tpacpi_subdriver(ibm);
+		if (ret)
+			goto err_out;
+	}
+
+	if (ibm->notify) {
+		ret = setup_notify(ibm);
+		if (ret == -ENODEV) {
+			printk(IBM_NOTICE "disabling subdriver %s\n",
+				ibm->name);
+			ret = 0;
+			goto err_out;
+		}
+		if (ret < 0)
+			goto err_out;
+	}
+
 	if (ibm->read) {
 		entry = create_proc_entry(ibm->name,
 					  S_IFREG | S_IRUGO | S_IWUSR,
@@ -2592,7 +2664,8 @@ static int __init ibm_init(struct ibm_struct *ibm)
 		if (!entry) {
 			printk(IBM_ERR "unable to create proc entry %s\n",
 			       ibm->name);
-			return -ENODEV;
+			ret = -ENODEV;
+			goto err_out;
 		}
 		entry->owner = THIS_MODULE;
 		entry->data = ibm;
@@ -2602,36 +2675,36 @@ static int __init ibm_init(struct ibm_struct *ibm)
 		ibm->proc_created = 1;
 	}
 
-	if (ibm->notify) {
-		ret = setup_notify(ibm);
-		if (ret == -ENODEV) {
-			printk(IBM_NOTICE "disabling subdriver %s\n",
-				ibm->name);
-			ibm_exit(ibm);
-			return 0;
-		}
-		if (ret < 0)
-			return ret;
-	}
-
 	return 0;
+
+err_out:
+	ibm_exit(ibm);
+	return (ret < 0)? ret : 0;
 }
 
 static void ibm_exit(struct ibm_struct *ibm)
 {
-	if (ibm->notify_installed)
+	if (ibm->notify_installed) {
 		acpi_remove_notify_handler(*ibm->handle, ibm->type,
 					   dispatch_notify);
+		ibm->notify_installed = 0;
+	}
 
-	if (ibm->proc_created)
+	if (ibm->proc_created) {
 		remove_proc_entry(ibm->name, proc_dir);
-
-	if (ibm->init_called && ibm->exit)
-		ibm->exit();
+		ibm->proc_created = 0;
+	}
 
 	if (ibm->driver_registered) {
 		acpi_bus_unregister_driver(ibm->driver);
 		kfree(ibm->driver);
+		ibm->driver = NULL;
+		ibm->driver_registered = 0;
+	}
+
+	if (ibm->init_called && ibm->exit) {
+		ibm->exit();
+		ibm->init_called = 0;
 	}
 }
 
@@ -2663,6 +2736,32 @@ static char* __init check_dmi_for_ec(void)
 	return NULL;
 }
 
+static int __init probe_for_thinkpad(void)
+{
+	int is_thinkpad;
+
+	if (acpi_disabled)
+		return -ENODEV;
+
+	/*
+	 * Non-ancient models have better DMI tagging, but very old models
+	 * don't.
+	 */
+	is_thinkpad = dmi_name_in_vendors("ThinkPad");
+
+	/* ec is required because many other handles are relative to it */
+	IBM_HANDLE_INIT(ec);
+	if (!ec_handle) {
+		if (is_thinkpad)
+			printk(IBM_ERR
+				"Not yet supported ThinkPad detected!\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+
 /* Module init, exit, parameters */
 
 static int __init set_ibm_param(const char *val, struct kernel_param *kp)
@@ -2712,45 +2811,13 @@ static int __init thinkpad_acpi_module_init(void)
 {
 	int ret, i;
 
-	if (acpi_disabled)
-		return -ENODEV;
+	ret = probe_for_thinkpad();
+	if (ret)
+		return ret;
 
-	/* ec is required because many other handles are relative to it */
-	IBM_HANDLE_INIT(ec);
-	if (!ec_handle) {
-		printk(IBM_ERR "ec object not found\n");
-		return -ENODEV;
-	}
-
-	/* Models with newer firmware report the EC in DMI */
 	ibm_thinkpad_ec_found = check_dmi_for_ec();
-
-	/* these handles are not required */
-	IBM_HANDLE_INIT(vid);
-	IBM_HANDLE_INIT(vid2);
-	IBM_HANDLE_INIT(ledb);
-	IBM_HANDLE_INIT(led);
-	IBM_HANDLE_INIT(hkey);
-	IBM_HANDLE_INIT(lght);
-	IBM_HANDLE_INIT(cmos);
-#ifdef CONFIG_THINKPAD_ACPI_DOCK
-	IBM_HANDLE_INIT(dock);
-#endif
-	IBM_HANDLE_INIT(pci);
-#ifdef CONFIG_THINKPAD_ACPI_BAY
-	IBM_HANDLE_INIT(bay);
-	if (bay_handle)
-		IBM_HANDLE_INIT(bay_ej);
-	IBM_HANDLE_INIT(bay2);
-	if (bay2_handle)
-		IBM_HANDLE_INIT(bay2_ej);
-#endif /* CONFIG_THINKPAD_ACPI_BAY */
-	IBM_HANDLE_INIT(beep);
 	IBM_HANDLE_INIT(ecrd);
 	IBM_HANDLE_INIT(ecwr);
-	IBM_HANDLE_INIT(fans);
-	IBM_HANDLE_INIT(gfan);
-	IBM_HANDLE_INIT(sfan);
 
 	proc_dir = proc_mkdir(IBM_DIR, acpi_root_dir);
 	if (!proc_dir) {
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index b2348d7..06d4c38 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -104,7 +104,7 @@ static acpi_handle ecrd_handle, ecwr_handle;	/* 570 EC access */
 static acpi_handle cmos_handle, hkey_handle;	/* basic thinkpad handles */
 
 static void ibm_handle_init(char *name,
-		   acpi_handle * handle, acpi_handle parent,
+		   acpi_handle *handle, acpi_handle parent,
 		   char **paths, int num_paths, char **path);
 #define IBM_HANDLE_INIT(object)						\
 	ibm_handle_init(#object, &object##_handle, *object##_parent,	\
@@ -242,8 +242,8 @@ static int cmos_write(char *buf);
  * Dock subdriver
  */
 
-static acpi_handle pci_handle;
 #ifdef CONFIG_THINKPAD_ACPI_DOCK
+static acpi_handle pci_handle;
 static acpi_handle dock_handle;
 
 static void dock_notify(struct ibm_struct *ibm, u32 event);
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 053/105] ACPI: thinkpad-acpi: add subdriver debug statements
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Add debug messages to the subdriver initialization and exit code.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 Documentation/thinkpad-acpi.txt |    4 ++
 drivers/misc/thinkpad_acpi.c    |  111 +++++++++++++++++++++++++++++++++++++++
 drivers/misc/thinkpad_acpi.h    |    4 ++
 3 files changed, 119 insertions(+), 0 deletions(-)

diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt
index 82fd822..20d5ec3 100644
--- a/Documentation/thinkpad-acpi.txt
+++ b/Documentation/thinkpad-acpi.txt
@@ -710,5 +710,9 @@ enable various classes of debugging output, for example:
 will enable all debugging output classes.  It takes a bitmask, so
 to enable more than one output class, just add their values.
 
+	Debug bitmask		Description
+	0x0001			Initialization and probing
+	0x0002			Removal
+
 There is also a kernel build option to enable more debugging
 information, which may be necessary to debug driver problems.
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index eeab394..e8fc8da 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -313,6 +313,9 @@ static int __init setup_notify(struct ibm_struct *ibm)
 	if (!*ibm->handle)
 		return 0;
 
+	dbg_printk(TPACPI_DBG_INIT,
+		"setting up ACPI notify for %s\n", ibm->name);
+
 	ret = acpi_bus_get_device(*ibm->handle, &ibm->device);
 	if (ret < 0) {
 		printk(IBM_ERR "%s device not present\n", ibm->name);
@@ -349,6 +352,9 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm)
 {
 	int ret;
 
+	dbg_printk(TPACPI_DBG_INIT,
+		"registering %s as an ACPI driver\n", ibm->name);
+
 	ibm->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL);
 	if (!ibm->driver) {
 		printk(IBM_ERR "kzalloc(ibm->driver) failed\n");
@@ -497,17 +503,25 @@ static int hotkey_orig_mask;
 
 static int hotkey_init(void)
 {
+	vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n");
+
 	IBM_HANDLE_INIT(hkey);
 
 	/* hotkey not supported on 570 */
 	hotkey_supported = hkey_handle != NULL;
 
+	vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n",
+		str_supported(hotkey_supported));
+
 	if (hotkey_supported) {
 		/* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
 		   A30, R30, R31, T20-22, X20-21, X22-24 */
 		hotkey_mask_supported =
 		    acpi_evalf(hkey_handle, NULL, "DHKN", "qv");
 
+		vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n",
+			str_supported(hotkey_mask_supported));
+
 		if (!hotkey_get(&hotkey_orig_status, &hotkey_orig_mask))
 			return -ENODEV;
 	}
@@ -518,6 +532,7 @@ static int hotkey_init(void)
 static void hotkey_exit(void)
 {
 	if (hotkey_supported) {
+		dbg_printk(TPACPI_DBG_EXIT, "restoring original hotkey mask\n");
 		hotkey_set(hotkey_orig_status, hotkey_orig_mask);
 	}
 }
@@ -633,6 +648,8 @@ static int bluetooth_supported;
 
 static int bluetooth_init(void)
 {
+	vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n");
+
 	IBM_HANDLE_INIT(hkey);
 
 	/* bluetooth not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
@@ -640,6 +657,9 @@ static int bluetooth_init(void)
 	bluetooth_supported = hkey_handle &&
 	    acpi_evalf(hkey_handle, NULL, "GBDC", "qv");
 
+	vdbg_printk(TPACPI_DBG_INIT, "bluetooth is %s\n",
+		str_supported(bluetooth_supported));
+
 	return (bluetooth_supported)? 0 : 1;
 }
 
@@ -704,11 +724,16 @@ static int wan_supported;
 
 static int wan_init(void)
 {
+	vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n");
+
 	IBM_HANDLE_INIT(hkey);
 
 	wan_supported = hkey_handle &&
 	    acpi_evalf(hkey_handle, NULL, "GWAN", "qv");
 
+	vdbg_printk(TPACPI_DBG_INIT, "wan is %s\n",
+		str_supported(wan_supported));
+
 	return (wan_supported)? 0 : 1;
 }
 
@@ -784,6 +809,8 @@ static int video_init(void)
 {
 	int ivga;
 
+	vdbg_printk(TPACPI_DBG_INIT, "initializing video subdriver\n");
+
 	IBM_HANDLE_INIT(vid);
 	IBM_HANDLE_INIT(vid2);
 
@@ -804,11 +831,16 @@ static int video_init(void)
 		/* all others */
 		video_supported = TPACPI_VIDEO_NEW;
 
+	vdbg_printk(TPACPI_DBG_INIT, "video is %s, mode %d\n",
+		str_supported(video_supported != TPACPI_VIDEO_NONE),
+		video_supported);
+
 	return (video_supported != TPACPI_VIDEO_NONE)? 0 : 1;
 }
 
 static void video_exit(void)
 {
+	dbg_printk(TPACPI_DBG_EXIT, "restoring original video autoswitch mode\n");
 	acpi_evalf(vid_handle, NULL, "_DOS", "vd", video_orig_autosw);
 }
 
@@ -991,6 +1023,8 @@ IBM_HANDLE(ledb, ec, "LEDB");		/* G4x */
 
 static int light_init(void)
 {
+	vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n");
+
 	IBM_HANDLE_INIT(ledb);
 	IBM_HANDLE_INIT(lght);
 	IBM_HANDLE_INIT(cmos);
@@ -1004,6 +1038,9 @@ static int light_init(void)
 		light_status_supported = acpi_evalf(ec_handle, NULL,
 						    "KBLT", "qv");
 
+	vdbg_printk(TPACPI_DBG_INIT, "light is %s\n",
+		str_supported(light_supported));
+
 	return (light_supported)? 0 : 1;
 }
 
@@ -1075,9 +1112,14 @@ IBM_HANDLE(pci, root, "\\_SB.PCI");	/* 570 */
 
 static int dock_init(void)
 {
+	vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver\n");
+
 	IBM_HANDLE_INIT(dock);
 	IBM_HANDLE_INIT(pci);
 
+	vdbg_printk(TPACPI_DBG_INIT, "dock is %s\n",
+		str_supported(dock_handle != NULL));
+
 	return (dock_handle)? 0 : 1;
 }
 
@@ -1171,6 +1213,8 @@ IBM_HANDLE(bay2_ej, bay2, "_EJ3",	/* 600e/x, 770e, A3x */
 
 static int bay_init(void)
 {
+	vdbg_printk(TPACPI_DBG_INIT, "initializing bay subdriver\n");
+
 	IBM_HANDLE_INIT(bay);
 	if (bay_handle)
 		IBM_HANDLE_INIT(bay_ej);
@@ -1188,6 +1232,13 @@ static int bay_init(void)
 	bay_eject2_supported = bay2_handle && bay2_ej_handle &&
 	    (strlencmp(bay2_ej_path, "_EJ0") == 0 || experimental);
 
+	vdbg_printk(TPACPI_DBG_INIT,
+		"bay 1: status %s, eject %s; bay 2: status %s, eject %s\n",
+		str_supported(bay_status_supported),
+		str_supported(bay_eject_supported),
+		str_supported(bay_status2_supported),
+		str_supported(bay_eject2_supported));
+
 	return (bay_status_supported || bay_eject_supported ||
 		bay_status2_supported || bay_eject2_supported)? 0 : 1;
 }
@@ -1255,8 +1306,13 @@ static int bay_write(char *buf)
 
 static int cmos_init(void)
 {
+	vdbg_printk(TPACPI_DBG_INIT,
+		"initializing cmos commands subdriver\n");
+
 	IBM_HANDLE_INIT(cmos);
 
+	vdbg_printk(TPACPI_DBG_INIT, "cmos commands are %s\n",
+		str_supported(cmos_handle != NULL));
 	return (cmos_handle)? 0 : 1;
 }
 
@@ -1320,6 +1376,8 @@ IBM_HANDLE(led, ec, "SLED",	/* 570 */
 
 static int led_init(void)
 {
+	vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n");
+
 	IBM_HANDLE_INIT(led);
 
 	if (!led_handle)
@@ -1335,6 +1393,9 @@ static int led_init(void)
 		/* all others */
 		led_supported = TPACPI_LED_NEW;
 
+	vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n",
+		str_supported(led_supported), led_supported);
+
 	return (led_supported != TPACPI_LED_NONE)? 0 : 1;
 }
 
@@ -1434,8 +1495,13 @@ IBM_HANDLE(beep, ec, "BEEP");	/* all except R30, R31 */
 
 static int beep_init(void)
 {
+	vdbg_printk(TPACPI_DBG_INIT, "initializing beep subdriver\n");
+
 	IBM_HANDLE_INIT(beep);
 
+	vdbg_printk(TPACPI_DBG_INIT, "beep is %s\n",
+		str_supported(beep_handle != NULL));
+
 	return (beep_handle)? 0 : 1;
 }
 
@@ -1486,6 +1552,8 @@ static int thermal_init(void)
 	int i;
 	int acpi_tmp7;
 
+	vdbg_printk(TPACPI_DBG_INIT, "initializing thermal subdriver\n");
+
 	acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv");
 
 	if (ibm_thinkpad_ec_found && experimental) {
@@ -1542,6 +1610,10 @@ static int thermal_init(void)
 		thermal_read_mode = TPACPI_THERMAL_NONE;
 	}
 
+	vdbg_printk(TPACPI_DBG_INIT, "thermal is %s, mode %d\n",
+		str_supported(thermal_read_mode != TPACPI_THERMAL_NONE),
+		thermal_read_mode);
+
 	return (thermal_read_mode != TPACPI_THERMAL_NONE)? 0 : 1;
 }
 
@@ -1698,6 +1770,8 @@ static int brightness_init(void)
 {
 	int b;
 
+	vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n");
+
 	b = brightness_get(NULL);
 	if (b < 0)
 		return b;
@@ -1708,6 +1782,7 @@ static int brightness_init(void)
 		printk(IBM_ERR "Could not register backlight device\n");
 		return PTR_ERR(ibm_backlight_device);
 	}
+	vdbg_printk(TPACPI_DBG_INIT, "brightness is supported\n");
 
 	ibm_backlight_device->props.max_brightness = 7;
 	ibm_backlight_device->props.brightness = b;
@@ -1719,6 +1794,8 @@ static int brightness_init(void)
 static void brightness_exit(void)
 {
 	if (ibm_backlight_device) {
+		vdbg_printk(TPACPI_DBG_EXIT,
+			    "calling backlight_device_unregister()\n");
 		backlight_device_unregister(ibm_backlight_device);
 		ibm_backlight_device = NULL;
 	}
@@ -2017,6 +2094,8 @@ IBM_HANDLE(sfan, ec, "SFAN",	/* 570 */
 
 static int fan_init(void)
 {
+	vdbg_printk(TPACPI_DBG_INIT, "initializing fan subdriver\n");
+
 	fan_status_access_mode = TPACPI_FAN_NONE;
 	fan_control_access_mode = TPACPI_FAN_WR_NONE;
 	fan_control_commands = 0;
@@ -2095,6 +2174,11 @@ static int fan_init(void)
 		}
 	}
 
+	vdbg_printk(TPACPI_DBG_INIT, "fan is %s, modes %d, %d\n",
+		str_supported(fan_status_access_mode != TPACPI_FAN_NONE ||
+		  fan_control_access_mode != TPACPI_FAN_WR_NONE),
+		fan_status_access_mode, fan_control_access_mode);
+
 	return (fan_status_access_mode != TPACPI_FAN_NONE ||
 	        fan_control_access_mode != TPACPI_FAN_WR_NONE)?
 			0 : 1;
@@ -2138,6 +2222,7 @@ static int fan_get_status(u8 *status)
 
 static void fan_exit(void)
 {
+	vdbg_printk(TPACPI_DBG_EXIT, "cancelling any pending watchdogs\n");
 	cancel_delayed_work(&fan_watchdog_task);
 	flush_scheduled_work();
 }
@@ -2622,6 +2707,15 @@ static struct ibm_struct ibms[] = {
  * Module and infrastructure proble, init and exit handling
  */
 
+#ifdef CONFIG_THINKPAD_ACPI_DEBUG
+static const char * str_supported(int is_supported)
+{
+	static const char * const text_unsupported = "not supported";
+
+	return (is_supported)? text_unsupported + 4 : text_unsupported;
+}
+#endif /* CONFIG_THINKPAD_ACPI_DEBUG */
+
 static int __init ibm_init(struct ibm_struct *ibm)
 {
 	int ret;
@@ -2630,6 +2724,9 @@ static int __init ibm_init(struct ibm_struct *ibm)
 	if (ibm->experimental && !experimental)
 		return 0;
 
+	dbg_printk(TPACPI_DBG_INIT,
+		"probing for %s\n", ibm->name);
+
 	if (ibm->init) {
 		ret = ibm->init();
 		if (ret > 0)
@@ -2657,6 +2754,9 @@ static int __init ibm_init(struct ibm_struct *ibm)
 			goto err_out;
 	}
 
+	dbg_printk(TPACPI_DBG_INIT,
+		"%s installed\n", ibm->name);
+
 	if (ibm->read) {
 		entry = create_proc_entry(ibm->name,
 					  S_IFREG | S_IRUGO | S_IWUSR,
@@ -2678,24 +2778,35 @@ static int __init ibm_init(struct ibm_struct *ibm)
 	return 0;
 
 err_out:
+	dbg_printk(TPACPI_DBG_INIT,
+		"%s: at error exit path with result %d\n",
+		ibm->name, ret);
+
 	ibm_exit(ibm);
 	return (ret < 0)? ret : 0;
 }
 
 static void ibm_exit(struct ibm_struct *ibm)
 {
+	dbg_printk(TPACPI_DBG_EXIT, "removing %s\n", ibm->name);
 	if (ibm->notify_installed) {
+		dbg_printk(TPACPI_DBG_EXIT,
+			"%s: acpi_remove_notify_handler\n", ibm->name);
 		acpi_remove_notify_handler(*ibm->handle, ibm->type,
 					   dispatch_notify);
 		ibm->notify_installed = 0;
 	}
 
 	if (ibm->proc_created) {
+		dbg_printk(TPACPI_DBG_EXIT,
+			"%s: remove_proc_entry\n", ibm->name);
 		remove_proc_entry(ibm->name, proc_dir);
 		ibm->proc_created = 0;
 	}
 
 	if (ibm->driver_registered) {
+		dbg_printk(TPACPI_DBG_EXIT,
+			"%s: acpi_bus_unregister_driver\n", ibm->name);
 		acpi_bus_unregister_driver(ibm->driver);
 		kfree(ibm->driver);
 		ibm->driver = NULL;
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 06d4c38..beb1447 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -76,12 +76,16 @@
 
 /* Debugging */
 #define TPACPI_DBG_ALL		0xffff
+#define TPACPI_DBG_ALL		0xffff
+#define TPACPI_DBG_INIT		0x0001
+#define TPACPI_DBG_EXIT		0x0002
 #define dbg_printk(a_dbg_level, format, arg...) \
 	do { if (dbg_level & a_dbg_level) \
 		printk(IBM_DEBUG "%s: " format, __func__ , ## arg); } while (0)
 #ifdef CONFIG_THINKPAD_ACPI_DEBUG
 #define vdbg_printk(a_dbg_level, format, arg...) \
 	dbg_printk(a_dbg_level, format, ## arg)
+static const char *str_supported(int is_supported);
 #else
 #define vdbg_printk(a_dbg_level, format, arg...)
 #endif
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 054/105] ACPI: thinkpad-acpi: uncouple subdriver init from ibms struct
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi
  Cc: Henrique de Moraes Holschuh, Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@debian.org>

Move the .init method from ibms struct to another struct, and use a list
head to control which subdrivers have been activated.

This allows us to have the subdriver init methods marked __init, saving
quite a lot of .text size, and even a bit of .data size as some data can
now be made __initdata.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |  402 ++++++++++++++++++++++++++----------------
 drivers/misc/thinkpad_acpi.h |   51 +++---
 2 files changed, 278 insertions(+), 175 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index e8fc8da..5611268 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -470,7 +470,7 @@ static char *next_cmd(char **cmds)
  * thinkpad-acpi init subdriver
  */
 
-static int thinkpad_acpi_driver_init(void)
+static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm)
 {
 	printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION);
 	printk(IBM_INFO "%s\n", IBM_URL);
@@ -492,6 +492,11 @@ static int thinkpad_acpi_driver_read(char *p)
 	return len;
 }
 
+static struct ibm_struct thinkpad_acpi_driver_data = {
+	.name = "driver",
+	.read = thinkpad_acpi_driver_read,
+};
+
 /*************************************************************************
  * Hotkey subdriver
  */
@@ -501,7 +506,7 @@ static int hotkey_mask_supported;
 static int hotkey_orig_status;
 static int hotkey_orig_mask;
 
-static int hotkey_init(void)
+static int __init hotkey_init(struct ibm_init_struct *iibm)
 {
 	vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n");
 
@@ -640,13 +645,24 @@ static int hotkey_write(char *buf)
 	return 0;
 }
 
+static struct ibm_struct hotkey_driver_data = {
+	.name = "hotkey",
+	.hid = IBM_HKEY_HID,
+	.read = hotkey_read,
+	.write = hotkey_write,
+	.exit = hotkey_exit,
+	.notify = hotkey_notify,
+	.handle = &hkey_handle,
+	.type = ACPI_DEVICE_NOTIFY,
+};
+
 /*************************************************************************
  * Bluetooth subdriver
  */
 
 static int bluetooth_supported;
 
-static int bluetooth_init(void)
+static int __init bluetooth_init(struct ibm_init_struct *iibm)
 {
 	vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n");
 
@@ -716,13 +732,19 @@ static int bluetooth_write(char *buf)
 	return 0;
 }
 
+static struct ibm_struct bluetooth_driver_data = {
+	.name = "bluetooth",
+	.read = bluetooth_read,
+	.write = bluetooth_write,
+};
+
 /*************************************************************************
  * Wan subdriver
  */
 
 static int wan_supported;
 
-static int wan_init(void)
+static int __init wan_init(struct ibm_init_struct *iibm)
 {
 	vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n");
 
@@ -789,6 +811,13 @@ static int wan_write(char *buf)
 	return 0;
 }
 
+static struct ibm_struct wan_driver_data = {
+	.name = "wan",
+	.read = wan_read,
+	.write = wan_write,
+	.experimental = 1,
+};
+
 /*************************************************************************
  * Video subdriver
  */
@@ -805,7 +834,7 @@ IBM_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA",	/* 570 */
 
 IBM_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID");	/* G41 */
 
-static int video_init(void)
+static int __init video_init(struct ibm_init_struct *iibm)
 {
 	int ivga;
 
@@ -1011,6 +1040,13 @@ static int video_write(char *buf)
 	return 0;
 }
 
+static struct ibm_struct video_driver_data = {
+	.name = "video",
+	.read = video_read,
+	.write = video_write,
+	.exit = video_exit,
+};
+
 /*************************************************************************
  * Light (thinklight) subdriver
  */
@@ -1021,7 +1057,7 @@ static int light_status_supported;
 IBM_HANDLE(lght, root, "\\LGHT");	/* A21e, A2xm/p, T20-22, X20-21 */
 IBM_HANDLE(ledb, ec, "LEDB");		/* G4x */
 
-static int light_init(void)
+static int __init light_init(struct ibm_init_struct *iibm)
 {
 	vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n");
 
@@ -1093,6 +1129,12 @@ static int light_write(char *buf)
 	return 0;
 }
 
+static struct ibm_struct light_driver_data = {
+	.name = "light",
+	.read = light_read,
+	.write = light_write,
+};
+
 /*************************************************************************
  * Dock subdriver
  */
@@ -1110,7 +1152,7 @@ IBM_HANDLE(pci, root, "\\_SB.PCI");	/* 570 */
 
 #define dock_docked() (_sta(dock_handle) & 1)
 
-static int dock_init(void)
+static int __init dock_init(struct ibm_init_struct *iibm)
 {
 	vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver\n");
 
@@ -1184,6 +1226,24 @@ static int dock_write(char *buf)
 	return 0;
 }
 
+static struct ibm_struct dock_driver_data[2] = {
+	{
+	 .name = "dock",
+	 .read = dock_read,
+	 .write = dock_write,
+	 .notify = dock_notify,
+	 .handle = &dock_handle,
+	 .type = ACPI_SYSTEM_NOTIFY,
+	},
+	{
+	 .name = "dock",
+	 .hid = IBM_PCI_HID,
+	 .notify = dock_notify,
+	 .handle = &pci_handle,
+	 .type = ACPI_SYSTEM_NOTIFY,
+	},
+};
+
 #endif /* CONFIG_THINKPAD_ACPI_DOCK */
 
 /*************************************************************************
@@ -1211,7 +1271,7 @@ IBM_HANDLE(bay2_ej, bay2, "_EJ3",	/* 600e/x, 770e, A3x */
 	   "_EJ0",			/* 770x */
 	   );				/* all others */
 
-static int bay_init(void)
+static int __init bay_init(struct ibm_init_struct *iibm)
 {
 	vdbg_printk(TPACPI_DBG_INIT, "initializing bay subdriver\n");
 
@@ -1298,13 +1358,23 @@ static int bay_write(char *buf)
 
 	return 0;
 }
+
+static struct ibm_struct bay_driver_data = {
+	.name = "bay",
+	.read = bay_read,
+	.write = bay_write,
+	.notify = bay_notify,
+	.handle = &bay_handle,
+	.type = ACPI_SYSTEM_NOTIFY,
+};
+
 #endif /* CONFIG_THINKPAD_ACPI_BAY */
 
 /*************************************************************************
  * CMOS subdriver
  */
 
-static int cmos_init(void)
+static int __init cmos_init(struct ibm_init_struct *iibm)
 {
 	vdbg_printk(TPACPI_DBG_INIT,
 		"initializing cmos commands subdriver\n");
@@ -1362,6 +1432,11 @@ static int cmos_write(char *buf)
 	return 0;
 }
 
+static struct ibm_struct cmos_driver_data = {
+	.name = "cmos",
+	.read = cmos_read,
+	.write = cmos_write,
+};
 
 /*************************************************************************
  * LED subdriver
@@ -1374,7 +1449,7 @@ IBM_HANDLE(led, ec, "SLED",	/* 570 */
 	   "LED",		/* all others */
 	   );			/* R30, R31 */
 
-static int led_init(void)
+static int __init led_init(struct ibm_init_struct *iibm)
 {
 	vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n");
 
@@ -1487,13 +1562,19 @@ static int led_write(char *buf)
 	return 0;
 }
 
+static struct ibm_struct led_driver_data = {
+	.name = "led",
+	.read = led_read,
+	.write = led_write,
+};
+
 /*************************************************************************
  * Beep subdriver
  */
 
 IBM_HANDLE(beep, ec, "BEEP");	/* all except R30, R31 */
 
-static int beep_init(void)
+static int __init beep_init(struct ibm_init_struct *iibm)
 {
 	vdbg_printk(TPACPI_DBG_INIT, "initializing beep subdriver\n");
 
@@ -1540,13 +1621,19 @@ static int beep_write(char *buf)
 	return 0;
 }
 
+static struct ibm_struct beep_driver_data = {
+	.name = "beep",
+	.read = beep_read,
+	.write = beep_write,
+};
+
 /*************************************************************************
  * Thermal subdriver
  */
 
 static enum thermal_access_mode thermal_read_mode;
 
-static int thermal_init(void)
+static int __init thermal_init(struct ibm_init_struct *iibm)
 {
 	u8 t, ta1, ta2;
 	int i;
@@ -1692,6 +1779,11 @@ static int thermal_read(char *p)
 	return len;
 }
 
+static struct ibm_struct thermal_driver_data = {
+	.name = "thermal",
+	.read = thermal_read,
+};
+
 /*************************************************************************
  * EC Dump subdriver
  */
@@ -1755,6 +1847,13 @@ static int ecdump_write(char *buf)
 	return 0;
 }
 
+static struct ibm_struct ecdump_driver_data = {
+	.name = "ecdump",
+	.read = ecdump_read,
+	.write = ecdump_write,
+	.experimental = 1,
+};
+
 /*************************************************************************
  * Backlight/brightness subdriver
  */
@@ -1766,7 +1865,7 @@ static struct backlight_ops ibm_backlight_data = {
         .update_status  = brightness_update_status,
 };
 
-static int brightness_init(void)
+static int __init brightness_init(struct ibm_init_struct *iibm)
 {
 	int b;
 
@@ -1883,6 +1982,13 @@ static int brightness_write(char *buf)
 	return 0;
 }
 
+static struct ibm_struct brightness_driver_data = {
+	.name = "brightness",
+	.read = brightness_read,
+	.write = brightness_write,
+	.exit = brightness_exit,
+};
+
 /*************************************************************************
  * Volume subdriver
  */
@@ -1967,6 +2073,11 @@ static int volume_write(char *buf)
 	return 0;
 }
 
+static struct ibm_struct volume_driver_data = {
+	.name = "volume",
+	.read = volume_read,
+	.write = volume_write,
+};
 
 /*************************************************************************
  * Fan subdriver
@@ -2092,7 +2203,7 @@ IBM_HANDLE(sfan, ec, "SFAN",	/* 570 */
 	   "JFNS",		/* 770x-JL */
 	   );			/* all others */
 
-static int fan_init(void)
+static int __init fan_init(struct ibm_init_struct *iibm)
 {
 	vdbg_printk(TPACPI_DBG_INIT, "initializing fan subdriver\n");
 
@@ -2568,6 +2679,14 @@ static int fan_write(char *buf)
 	return rc;
 }
 
+static struct ibm_struct fan_driver_data = {
+	.name = "fan",
+	.read = fan_read,
+	.write = fan_write,
+	.exit = fan_exit,
+	.experimental = 1,
+};
+
 /****************************************************************************
  ****************************************************************************
  *
@@ -2580,159 +2699,45 @@ static int fan_write(char *buf)
 static struct proc_dir_entry *proc_dir = NULL;
 
 /* Subdriver registry */
-static struct ibm_struct ibms[] = {
-	{
-	 .name = "driver",
-	 .init = thinkpad_acpi_driver_init,
-	 .read = thinkpad_acpi_driver_read,
-	 },
-	{
-	 .name = "hotkey",
-	 .hid = IBM_HKEY_HID,
-	 .init = hotkey_init,
-	 .read = hotkey_read,
-	 .write = hotkey_write,
-	 .exit = hotkey_exit,
-	 .notify = hotkey_notify,
-	 .handle = &hkey_handle,
-	 .type = ACPI_DEVICE_NOTIFY,
-	 },
-	{
-	 .name = "bluetooth",
-	 .init = bluetooth_init,
-	 .read = bluetooth_read,
-	 .write = bluetooth_write,
-	 },
-	{
-	 .name = "wan",
-	 .init = wan_init,
-	 .read = wan_read,
-	 .write = wan_write,
-	 .experimental = 1,
-	 },
-	{
-	 .name = "video",
-	 .init = video_init,
-	 .read = video_read,
-	 .write = video_write,
-	 .exit = video_exit,
-	 },
-	{
-	 .name = "light",
-	 .init = light_init,
-	 .read = light_read,
-	 .write = light_write,
-	 },
-#ifdef CONFIG_THINKPAD_ACPI_DOCK
-	{
-	 .name = "dock",
-	 .init = dock_init,
-	 .read = dock_read,
-	 .write = dock_write,
-	 .notify = dock_notify,
-	 .handle = &dock_handle,
-	 .type = ACPI_SYSTEM_NOTIFY,
-	 },
-	{
-	 .name = "dock",
-	 .hid = IBM_PCI_HID,
-	 .notify = dock_notify,
-	 .handle = &pci_handle,
-	 .type = ACPI_SYSTEM_NOTIFY,
-	 },
-#endif
-#ifdef CONFIG_THINKPAD_ACPI_BAY
-	{
-	 .name = "bay",
-	 .init = bay_init,
-	 .read = bay_read,
-	 .write = bay_write,
-	 .notify = bay_notify,
-	 .handle = &bay_handle,
-	 .type = ACPI_SYSTEM_NOTIFY,
-	 },
-#endif /* CONFIG_THINKPAD_ACPI_BAY */
-	{
-	 .name = "cmos",
-	 .init = cmos_init,
-	 .read = cmos_read,
-	 .write = cmos_write,
-	 },
-	{
-	 .name = "led",
-	 .init = led_init,
-	 .read = led_read,
-	 .write = led_write,
-	 },
-	{
-	 .name = "beep",
-	 .init = beep_init,
-	 .read = beep_read,
-	 .write = beep_write,
-	 },
-	{
-	 .name = "thermal",
-	 .init = thermal_init,
-	 .read = thermal_read,
-	 },
-	{
-	 .name = "ecdump",
-	 .read = ecdump_read,
-	 .write = ecdump_write,
-	 .experimental = 1,
-	 },
-	{
-	 .name = "brightness",
-	 .read = brightness_read,
-	 .write = brightness_write,
-	 .init = brightness_init,
-	 .exit = brightness_exit,
-	 },
-	{
-	 .name = "volume",
-	 .read = volume_read,
-	 .write = volume_write,
-	 },
-	{
-	 .name = "fan",
-	 .read = fan_read,
-	 .write = fan_write,
-	 .init = fan_init,
-	 .exit = fan_exit,
-	 .experimental = 1,
-	 },
-};
+static LIST_HEAD(tpacpi_all_drivers);
+
 
 /*
  * Module and infrastructure proble, init and exit handling
  */
 
 #ifdef CONFIG_THINKPAD_ACPI_DEBUG
-static const char * str_supported(int is_supported)
+static const char * __init str_supported(int is_supported)
 {
-	static const char * const text_unsupported = "not supported";
+	static char text_unsupported[] __initdata = "not supported";
 
-	return (is_supported)? text_unsupported + 4 : text_unsupported;
+	return (is_supported)? &text_unsupported[4] : &text_unsupported[0];
 }
 #endif /* CONFIG_THINKPAD_ACPI_DEBUG */
 
-static int __init ibm_init(struct ibm_struct *ibm)
+static int __init ibm_init(struct ibm_init_struct *iibm)
 {
 	int ret;
+	struct ibm_struct *ibm = iibm->data;
 	struct proc_dir_entry *entry;
 
+	BUG_ON(ibm == NULL);
+
+	INIT_LIST_HEAD(&ibm->all_drivers);
+
 	if (ibm->experimental && !experimental)
 		return 0;
 
 	dbg_printk(TPACPI_DBG_INIT,
 		"probing for %s\n", ibm->name);
 
-	if (ibm->init) {
-		ret = ibm->init();
+	if (iibm->init) {
+		ret = iibm->init(iibm);
 		if (ret > 0)
 			return 0;	/* probe failed */
 		if (ret)
 			return ret;
+
 		ibm->init_called = 1;
 	}
 
@@ -2775,6 +2780,8 @@ static int __init ibm_init(struct ibm_struct *ibm)
 		ibm->proc_created = 1;
 	}
 
+	list_add_tail(&ibm->all_drivers, &tpacpi_all_drivers);
+
 	return 0;
 
 err_out:
@@ -2789,6 +2796,9 @@ err_out:
 static void ibm_exit(struct ibm_struct *ibm)
 {
 	dbg_printk(TPACPI_DBG_EXIT, "removing %s\n", ibm->name);
+
+	list_del_init(&ibm->all_drivers);
+
 	if (ibm->notify_installed) {
 		dbg_printk(TPACPI_DBG_EXIT,
 			"%s: acpi_remove_notify_handler\n", ibm->name);
@@ -2817,6 +2827,8 @@ static void ibm_exit(struct ibm_struct *ibm)
 		ibm->exit();
 		ibm->init_called = 0;
 	}
+
+	dbg_printk(TPACPI_DBG_INIT, "finished removing %s\n", ibm->name);
 }
 
 /* Probing */
@@ -2875,18 +2887,95 @@ static int __init probe_for_thinkpad(void)
 
 /* Module init, exit, parameters */
 
+static struct ibm_init_struct ibms_init[] __initdata = {
+	{
+		.init = thinkpad_acpi_driver_init,
+		.data = &thinkpad_acpi_driver_data,
+	},
+	{
+		.init = hotkey_init,
+		.data = &hotkey_driver_data,
+	},
+	{
+		.init = bluetooth_init,
+		.data = &bluetooth_driver_data,
+	},
+	{
+		.init = wan_init,
+		.data = &wan_driver_data,
+	},
+	{
+		.init = video_init,
+		.data = &video_driver_data,
+	},
+	{
+		.init = light_init,
+		.data = &light_driver_data,
+	},
+#ifdef CONFIG_THINKPAD_ACPI_DOCK
+	{
+		.init = dock_init,
+		.data = &dock_driver_data[0],
+	},
+	{
+		.data = &dock_driver_data[1],
+	},
+#endif
+#ifdef CONFIG_THINKPAD_ACPI_BAY
+	{
+		.init = bay_init,
+		.data = &bay_driver_data,
+	},
+#endif
+	{
+		.init = cmos_init,
+		.data = &cmos_driver_data,
+	},
+	{
+		.init = led_init,
+		.data = &led_driver_data,
+	},
+	{
+		.init = beep_init,
+		.data = &beep_driver_data,
+	},
+	{
+		.init = thermal_init,
+		.data = &thermal_driver_data,
+	},
+	{
+		.data = &ecdump_driver_data,
+	},
+	{
+		.init = brightness_init,
+		.data = &brightness_driver_data,
+	},
+	{
+		.data = &volume_driver_data,
+	},
+	{
+		.init = fan_init,
+		.data = &fan_driver_data,
+	},
+};
+
 static int __init set_ibm_param(const char *val, struct kernel_param *kp)
 {
 	unsigned int i;
+	struct ibm_struct *ibm;
 
-	for (i = 0; i < ARRAY_SIZE(ibms); i++)
-		if (strcmp(ibms[i].name, kp->name) == 0 && ibms[i].write) {
-			if (strlen(val) > sizeof(ibms[i].param) - 2)
+	for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
+		ibm = ibms_init[i].data;
+		BUG_ON(ibm == NULL);
+
+		if (strcmp(ibm->name, kp->name) == 0 && ibm->write) {
+			if (strlen(val) > sizeof(ibms_init[i].param) - 2)
 				return -ENOSPC;
-			strcpy(ibms[i].param, val);
-			strcat(ibms[i].param, ",");
+			strcpy(ibms_init[i].param, val);
+			strcat(ibms_init[i].param, ",");
 			return 0;
 		}
+	}
 
 	return -EINVAL;
 }
@@ -2938,10 +3027,10 @@ static int __init thinkpad_acpi_module_init(void)
 	}
 	proc_dir->owner = THIS_MODULE;
 
-	for (i = 0; i < ARRAY_SIZE(ibms); i++) {
-		ret = ibm_init(&ibms[i]);
-		if (ret >= 0 && *ibms[i].param)
-			ret = ibms[i].write(ibms[i].param);
+	for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
+		ret = ibm_init(&ibms_init[i]);
+		if (ret >= 0 && *ibms_init[i].param)
+			ret = ibms_init[i].data->write(ibms_init[i].param);
 		if (ret < 0) {
 			thinkpad_acpi_module_exit();
 			return ret;
@@ -2953,10 +3042,15 @@ static int __init thinkpad_acpi_module_init(void)
 
 static void thinkpad_acpi_module_exit(void)
 {
-	int i;
+	struct ibm_struct *ibm, *itmp;
+
+	list_for_each_entry_safe_reverse(ibm, itmp,
+					 &tpacpi_all_drivers,
+					 all_drivers) {
+		ibm_exit(ibm);
+	}
 
-	for (i = ARRAY_SIZE(ibms) - 1; i >= 0; i--)
-		ibm_exit(&ibms[i]);
+	dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n");
 
 	if (proc_dir)
 		remove_proc_entry(IBM_DIR, acpi_root_dir);
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index beb1447..97467b7 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -29,6 +29,7 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/string.h>
+#include <linux/list.h>
 
 #include <linux/proc_fs.h>
 #include <linux/backlight.h>
@@ -116,8 +117,6 @@ static void ibm_handle_init(char *name,
 
 /* procfs support */
 static struct proc_dir_entry *proc_dir;
-static int thinkpad_acpi_driver_init(void);
-static int thinkpad_acpi_driver_read(char *p);
 
 /* procfs helpers */
 static int dispatch_read(char *page, char **start, off_t off, int count,
@@ -142,12 +141,10 @@ static void thinkpad_acpi_module_exit(void);
 
 struct ibm_struct {
 	char *name;
-	char param[32];
 
 	char *hid;
 	struct acpi_driver *driver;
 
-	int (*init) (void);
 	int (*read) (char *);
 	int (*write) (char *);
 	void (*exit) (void);
@@ -157,6 +154,8 @@ struct ibm_struct {
 	int type;
 	struct acpi_device *device;
 
+	struct list_head all_drivers;
+
 	int driver_registered;
 	int proc_created;
 	int init_called;
@@ -165,16 +164,26 @@ struct ibm_struct {
 	int experimental;
 };
 
-static struct ibm_struct ibms[];
+struct ibm_init_struct {
+	char param[32];
+
+	int (*init) (struct ibm_init_struct *);
+	struct ibm_struct *data;
+};
+
+static struct list_head tpacpi_all_drivers;
+
+static struct ibm_init_struct ibms_init[];
 static int set_ibm_param(const char *val, struct kernel_param *kp);
-static int ibm_init(struct ibm_struct *ibm);
+static int ibm_init(struct ibm_init_struct *iibm);
 static void ibm_exit(struct ibm_struct *ibm);
 
-/* ACPI devices */
-static void dispatch_notify(acpi_handle handle, u32 event, void *data);
-static int setup_notify(struct ibm_struct *ibm);
-static int ibm_device_add(struct acpi_device *device);
-static int register_tpacpi_subdriver(struct ibm_struct *ibm);
+
+/*
+ * procfs master subdriver
+ */
+static int thinkpad_acpi_driver_init(struct ibm_init_struct *iibm);
+static int thinkpad_acpi_driver_read(char *p);
 
 
 /*
@@ -188,7 +197,7 @@ static int bay_status2_supported, bay_eject2_supported;
 static acpi_handle bay_handle, bay_ej_handle;
 static acpi_handle bay2_handle, bay2_ej_handle;
 
-static int bay_init(void);
+static int bay_init(struct ibm_init_struct *iibm);
 static void bay_notify(struct ibm_struct *ibm, u32 event);
 static int bay_read(char *p);
 static int bay_write(char *buf);
@@ -211,7 +220,7 @@ static int beep_write(char *buf);
 
 static int bluetooth_supported;
 
-static int bluetooth_init(void);
+static int bluetooth_init(struct ibm_init_struct *iibm);
 static int bluetooth_status(void);
 static int bluetooth_read(char *p);
 static int bluetooth_write(char *buf);
@@ -224,7 +233,7 @@ static int bluetooth_write(char *buf);
 static struct backlight_device *ibm_backlight_device;
 static int brightness_offset = 0x31;
 
-static int brightness_init(void);
+static int brightness_init(struct ibm_init_struct *iibm);
 static void brightness_exit(void);
 static int brightness_get(struct backlight_device *bd);
 static int brightness_set(int value);
@@ -306,7 +315,7 @@ static int fan_watchdog_maxinterval;
 
 static acpi_handle fans_handle, gfan_handle, sfan_handle;
 
-static int fan_init(void);
+static int fan_init(struct ibm_init_struct *iibm);
 static void fan_exit(void);
 static int fan_get_status(u8 *status);
 static int fan_get_speed(unsigned int *speed);
@@ -334,7 +343,7 @@ static int hotkey_mask_supported;
 static int hotkey_orig_status;
 static int hotkey_orig_mask;
 
-static int hotkey_init(void);
+static int hotkey_init(struct ibm_init_struct *iibm);
 static void hotkey_exit(void);
 static int hotkey_get(int *status, int *mask);
 static int hotkey_set(int status, int mask);
@@ -363,7 +372,7 @@ enum {	/* For TPACPI_LED_OLD */
 static enum led_access_mode led_supported;
 static acpi_handle led_handle;
 
-static int led_init(void);
+static int led_init(struct ibm_init_struct *iibm);
 static int led_read(char *p);
 static int led_write(char *buf);
 
@@ -375,7 +384,7 @@ static int light_supported;
 static int light_status_supported;
 static acpi_handle lght_handle, ledb_handle;
 
-static int light_init(void);
+static int light_init(struct ibm_init_struct *iibm);
 static int light_read(char *p);
 static int light_write(char *buf);
 
@@ -397,7 +406,7 @@ struct ibm_thermal_sensors_struct {
 	s32 temp[TPACPI_MAX_THERMAL_SENSORS];
 };
 
-static int thermal_init(void);
+static int thermal_init(struct ibm_init_struct *iibm);
 static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s);
 static int thermal_read(char *p);
 
@@ -417,7 +426,7 @@ static enum video_access_mode video_supported;
 static int video_orig_autosw;
 static acpi_handle vid_handle, vid2_handle;
 
-static int video_init(void);
+static int video_init(struct ibm_init_struct *iibm);
 static void video_exit(void);
 static int video_status(void);
 static int video_autosw(void);
@@ -444,7 +453,7 @@ static int volume_write(char *buf);
 
 static int wan_supported;
 
-static int wan_init(void);
+static int wan_init(struct ibm_init_struct *iibm);
 static int wan_status(void);
 static int wan_read(char *p);
 static int wan_write(char *buf);
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 055/105] ACPI: thinkpad-acpi: improve thinkpad detection
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Improve the detection of ThinkPads, so as to reduce the chances of false
positives.

Since this could potentially add false negatives on the very old models,
add a module parameter to force the detection of a thinkpad.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 Documentation/thinkpad-acpi.txt |    7 +++++++
 drivers/misc/thinkpad_acpi.c    |   13 +++++++++++++
 drivers/misc/thinkpad_acpi.h    |    1 +
 3 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt
index 20d5ec3..1a42b77 100644
--- a/Documentation/thinkpad-acpi.txt
+++ b/Documentation/thinkpad-acpi.txt
@@ -716,3 +716,10 @@ to enable more than one output class, just add their values.
 
 There is also a kernel build option to enable more debugging
 information, which may be necessary to debug driver problems.
+
+Force loading of module
+-----------------------
+
+If thinkpad-acpi refuses to detect your ThinkPad, you can try to specify
+the module parameter force_load=1.  Regardless of whether this works or
+not, please contact ibm-acpi-devel@lists.sourceforge.net with a report.
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 5611268..cddf81b 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -2881,6 +2881,16 @@ static int __init probe_for_thinkpad(void)
 		return -ENODEV;
 	}
 
+	/*
+	 * Risks a regression on very old machines, but reduces potential
+	 * false positives a damn great deal
+	 */
+	if (!is_thinkpad)
+		is_thinkpad = dmi_name_in_vendors("IBM");
+
+	if (!is_thinkpad && !force_load)
+		return -ENODEV;
+
 	return 0;
 }
 
@@ -2986,6 +2996,9 @@ module_param(experimental, int, 0);
 static u32 dbg_level;
 module_param_named(debug, dbg_level, uint, 0);
 
+static int force_load;
+module_param(force_load, int, 0);
+
 #define IBM_PARAM(feature) \
 	module_param_call(feature, set_ibm_param, NULL, NULL, 0)
 
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 97467b7..2020398 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -128,6 +128,7 @@ static char *next_cmd(char **cmds);
 /* Module */
 static int experimental;
 static u32 dbg_level;
+static int force_load;
 static char *ibm_thinkpad_ec_found;
 
 static char* check_dmi_for_ec(void);
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 056/105] ACPI: thinkpad-acpi: use bitfields to hold subdriver flags
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Save some memory by using bitfields to hold boolean flags for the
subdrivers.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |   32 ++++++++++++++++----------------
 drivers/misc/thinkpad_acpi.h |   13 +++++++------
 2 files changed, 23 insertions(+), 22 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index cddf81b..a5efd06 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -339,7 +339,7 @@ static int __init setup_notify(struct ibm_struct *ibm)
 		}
 		return -ENODEV;
 	}
-	ibm->notify_installed = 1;
+	ibm->flags.notify_installed = 1;
 	return 0;
 }
 
@@ -372,7 +372,7 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm)
 		kfree(ibm->driver);
 		ibm->driver = NULL;
 	} else if (!ret)
-		ibm->driver_registered = 1;
+		ibm->flags.driver_registered = 1;
 
 	return ret;
 }
@@ -815,7 +815,7 @@ static struct ibm_struct wan_driver_data = {
 	.name = "wan",
 	.read = wan_read,
 	.write = wan_write,
-	.experimental = 1,
+	.flags.experimental = 1,
 };
 
 /*************************************************************************
@@ -1851,7 +1851,7 @@ static struct ibm_struct ecdump_driver_data = {
 	.name = "ecdump",
 	.read = ecdump_read,
 	.write = ecdump_write,
-	.experimental = 1,
+	.flags.experimental = 1,
 };
 
 /*************************************************************************
@@ -2684,7 +2684,7 @@ static struct ibm_struct fan_driver_data = {
 	.read = fan_read,
 	.write = fan_write,
 	.exit = fan_exit,
-	.experimental = 1,
+	.flags.experimental = 1,
 };
 
 /****************************************************************************
@@ -2725,7 +2725,7 @@ static int __init ibm_init(struct ibm_init_struct *iibm)
 
 	INIT_LIST_HEAD(&ibm->all_drivers);
 
-	if (ibm->experimental && !experimental)
+	if (ibm->flags.experimental && !experimental)
 		return 0;
 
 	dbg_printk(TPACPI_DBG_INIT,
@@ -2738,7 +2738,7 @@ static int __init ibm_init(struct ibm_init_struct *iibm)
 		if (ret)
 			return ret;
 
-		ibm->init_called = 1;
+		ibm->flags.init_called = 1;
 	}
 
 	if (ibm->hid) {
@@ -2777,7 +2777,7 @@ static int __init ibm_init(struct ibm_init_struct *iibm)
 		entry->read_proc = &dispatch_read;
 		if (ibm->write)
 			entry->write_proc = &dispatch_write;
-		ibm->proc_created = 1;
+		ibm->flags.proc_created = 1;
 	}
 
 	list_add_tail(&ibm->all_drivers, &tpacpi_all_drivers);
@@ -2799,33 +2799,33 @@ static void ibm_exit(struct ibm_struct *ibm)
 
 	list_del_init(&ibm->all_drivers);
 
-	if (ibm->notify_installed) {
+	if (ibm->flags.notify_installed) {
 		dbg_printk(TPACPI_DBG_EXIT,
 			"%s: acpi_remove_notify_handler\n", ibm->name);
 		acpi_remove_notify_handler(*ibm->handle, ibm->type,
 					   dispatch_notify);
-		ibm->notify_installed = 0;
+		ibm->flags.notify_installed = 0;
 	}
 
-	if (ibm->proc_created) {
+	if (ibm->flags.proc_created) {
 		dbg_printk(TPACPI_DBG_EXIT,
 			"%s: remove_proc_entry\n", ibm->name);
 		remove_proc_entry(ibm->name, proc_dir);
-		ibm->proc_created = 0;
+		ibm->flags.proc_created = 0;
 	}
 
-	if (ibm->driver_registered) {
+	if (ibm->flags.driver_registered) {
 		dbg_printk(TPACPI_DBG_EXIT,
 			"%s: acpi_bus_unregister_driver\n", ibm->name);
 		acpi_bus_unregister_driver(ibm->driver);
 		kfree(ibm->driver);
 		ibm->driver = NULL;
-		ibm->driver_registered = 0;
+		ibm->flags.driver_registered = 0;
 	}
 
-	if (ibm->init_called && ibm->exit) {
+	if (ibm->flags.init_called && ibm->exit) {
 		ibm->exit();
-		ibm->init_called = 0;
+		ibm->flags.init_called = 0;
 	}
 
 	dbg_printk(TPACPI_DBG_INIT, "finished removing %s\n", ibm->name);
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 2020398..8b72061 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -157,12 +157,13 @@ struct ibm_struct {
 
 	struct list_head all_drivers;
 
-	int driver_registered;
-	int proc_created;
-	int init_called;
-	int notify_installed;
-
-	int experimental;
+	struct {
+		u8 driver_registered:1;
+		u8 proc_created:1;
+		u8 init_called:1;
+		u8 notify_installed:1;
+		u8 experimental:1;
+	} flags;
 };
 
 struct ibm_init_struct {
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 057/105] ACPI: thinkpad-acpi: use bitfields for module flags
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Use a bitfield to hold boolean module-wide flags, to conserve some memory.
It is easy and it is clean, so we do it just for the heck of it even if it
saves very little space.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |  147 +++++++++++++++++++-----------------------
 drivers/misc/thinkpad_acpi.h |   28 +++++----
 2 files changed, 83 insertions(+), 92 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index a5efd06..e2a1b63 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -501,8 +501,6 @@ static struct ibm_struct thinkpad_acpi_driver_data = {
  * Hotkey subdriver
  */
 
-static int hotkey_supported;
-static int hotkey_mask_supported;
 static int hotkey_orig_status;
 static int hotkey_orig_mask;
 
@@ -513,30 +511,30 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
 	IBM_HANDLE_INIT(hkey);
 
 	/* hotkey not supported on 570 */
-	hotkey_supported = hkey_handle != NULL;
+	tp_features.hotkey = hkey_handle != NULL;
 
 	vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n",
-		str_supported(hotkey_supported));
+		str_supported(tp_features.hotkey));
 
-	if (hotkey_supported) {
+	if (tp_features.hotkey) {
 		/* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
 		   A30, R30, R31, T20-22, X20-21, X22-24 */
-		hotkey_mask_supported =
-		    acpi_evalf(hkey_handle, NULL, "DHKN", "qv");
+		tp_features.hotkey_mask =
+			acpi_evalf(hkey_handle, NULL, "DHKN", "qv");
 
 		vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n",
-			str_supported(hotkey_mask_supported));
+			str_supported(tp_features.hotkey_mask));
 
 		if (!hotkey_get(&hotkey_orig_status, &hotkey_orig_mask))
 			return -ENODEV;
 	}
 
-	return (hotkey_supported)? 0 : 1;
+	return (tp_features.hotkey)? 0 : 1;
 }
 
 static void hotkey_exit(void)
 {
-	if (hotkey_supported) {
+	if (tp_features.hotkey) {
 		dbg_printk(TPACPI_DBG_EXIT, "restoring original hotkey mask\n");
 		hotkey_set(hotkey_orig_status, hotkey_orig_mask);
 	}
@@ -559,7 +557,7 @@ static int hotkey_get(int *status, int *mask)
 	if (!acpi_evalf(hkey_handle, status, "DHKC", "d"))
 		return 0;
 
-	if (hotkey_mask_supported)
+	if (tp_features.hotkey_mask)
 		if (!acpi_evalf(hkey_handle, mask, "DHKN", "d"))
 			return 0;
 
@@ -573,7 +571,7 @@ static int hotkey_set(int status, int mask)
 	if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status))
 		return 0;
 
-	if (hotkey_mask_supported)
+	if (tp_features.hotkey_mask)
 		for (i = 0; i < 32; i++) {
 			int bit = ((1 << i) & mask) != 0;
 			if (!acpi_evalf(hkey_handle,
@@ -589,7 +587,7 @@ static int hotkey_read(char *p)
 	int status, mask;
 	int len = 0;
 
-	if (!hotkey_supported) {
+	if (!tp_features.hotkey) {
 		len += sprintf(p + len, "status:\t\tnot supported\n");
 		return len;
 	}
@@ -598,7 +596,7 @@ static int hotkey_read(char *p)
 		return -EIO;
 
 	len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0));
-	if (hotkey_mask_supported) {
+	if (tp_features.hotkey_mask) {
 		len += sprintf(p + len, "mask:\t\t0x%04x\n", mask);
 		len += sprintf(p + len,
 			       "commands:\tenable, disable, reset, <mask>\n");
@@ -616,7 +614,7 @@ static int hotkey_write(char *buf)
 	char *cmd;
 	int do_cmd = 0;
 
-	if (!hotkey_supported)
+	if (!tp_features.hotkey)
 		return -ENODEV;
 
 	if (!hotkey_get(&status, &mask))
@@ -660,8 +658,6 @@ static struct ibm_struct hotkey_driver_data = {
  * Bluetooth subdriver
  */
 
-static int bluetooth_supported;
-
 static int __init bluetooth_init(struct ibm_init_struct *iibm)
 {
 	vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n");
@@ -670,20 +666,20 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
 
 	/* bluetooth not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
 	   G4x, R30, R31, R40e, R50e, T20-22, X20-21 */
-	bluetooth_supported = hkey_handle &&
+	tp_features.bluetooth = hkey_handle &&
 	    acpi_evalf(hkey_handle, NULL, "GBDC", "qv");
 
 	vdbg_printk(TPACPI_DBG_INIT, "bluetooth is %s\n",
-		str_supported(bluetooth_supported));
+		str_supported(tp_features.bluetooth));
 
-	return (bluetooth_supported)? 0 : 1;
+	return (tp_features.bluetooth)? 0 : 1;
 }
 
 static int bluetooth_status(void)
 {
 	int status;
 
-	if (!bluetooth_supported ||
+	if (!tp_features.bluetooth ||
 	    !acpi_evalf(hkey_handle, &status, "GBDC", "d"))
 		status = 0;
 
@@ -695,7 +691,7 @@ static int bluetooth_read(char *p)
 	int len = 0;
 	int status = bluetooth_status();
 
-	if (!bluetooth_supported)
+	if (!tp_features.bluetooth)
 		len += sprintf(p + len, "status:\t\tnot supported\n");
 	else if (!(status & 1))
 		len += sprintf(p + len, "status:\t\tnot installed\n");
@@ -713,7 +709,7 @@ static int bluetooth_write(char *buf)
 	char *cmd;
 	int do_cmd = 0;
 
-	if (!bluetooth_supported)
+	if (!tp_features.bluetooth)
 		return -ENODEV;
 
 	while ((cmd = next_cmd(&buf))) {
@@ -742,28 +738,27 @@ static struct ibm_struct bluetooth_driver_data = {
  * Wan subdriver
  */
 
-static int wan_supported;
-
 static int __init wan_init(struct ibm_init_struct *iibm)
 {
 	vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n");
 
 	IBM_HANDLE_INIT(hkey);
 
-	wan_supported = hkey_handle &&
-	    acpi_evalf(hkey_handle, NULL, "GWAN", "qv");
+	tp_features.wan = hkey_handle &&
+			  acpi_evalf(hkey_handle, NULL, "GWAN", "qv");
 
 	vdbg_printk(TPACPI_DBG_INIT, "wan is %s\n",
-		str_supported(wan_supported));
+		str_supported(tp_features.wan));
 
-	return (wan_supported)? 0 : 1;
+	return (tp_features.wan)? 0 : 1;
 }
 
 static int wan_status(void)
 {
 	int status;
 
-	if (!wan_supported || !acpi_evalf(hkey_handle, &status, "GWAN", "d"))
+	if (!tp_features.wan ||
+	    !acpi_evalf(hkey_handle, &status, "GWAN", "d"))
 		status = 0;
 
 	return status;
@@ -774,7 +769,7 @@ static int wan_read(char *p)
 	int len = 0;
 	int status = wan_status();
 
-	if (!wan_supported)
+	if (!tp_features.wan)
 		len += sprintf(p + len, "status:\t\tnot supported\n");
 	else if (!(status & 1))
 		len += sprintf(p + len, "status:\t\tnot installed\n");
@@ -792,7 +787,7 @@ static int wan_write(char *buf)
 	char *cmd;
 	int do_cmd = 0;
 
-	if (!wan_supported)
+	if (!tp_features.wan)
 		return -ENODEV;
 
 	while ((cmd = next_cmd(&buf))) {
@@ -1051,9 +1046,6 @@ static struct ibm_struct video_driver_data = {
  * Light (thinklight) subdriver
  */
 
-static int light_supported;
-static int light_status_supported;
-
 IBM_HANDLE(lght, root, "\\LGHT");	/* A21e, A2xm/p, T20-22, X20-21 */
 IBM_HANDLE(ledb, ec, "LEDB");		/* G4x */
 
@@ -1066,18 +1058,18 @@ static int __init light_init(struct ibm_init_struct *iibm)
 	IBM_HANDLE_INIT(cmos);
 
 	/* light not supported on 570, 600e/x, 770e, 770x, G4x, R30, R31 */
-	light_supported = (cmos_handle || lght_handle) && !ledb_handle;
+	tp_features.light = (cmos_handle || lght_handle) && !ledb_handle;
 
-	if (light_supported)
+	if (tp_features.light)
 		/* light status not supported on
 		   570, 600e/x, 770e, 770x, G4x, R30, R31, R32, X20 */
-		light_status_supported = acpi_evalf(ec_handle, NULL,
-						    "KBLT", "qv");
+		tp_features.light_status =
+			acpi_evalf(ec_handle, NULL, "KBLT", "qv");
 
 	vdbg_printk(TPACPI_DBG_INIT, "light is %s\n",
-		str_supported(light_supported));
+		str_supported(tp_features.light));
 
-	return (light_supported)? 0 : 1;
+	return (tp_features.light)? 0 : 1;
 }
 
 static int light_read(char *p)
@@ -1085,9 +1077,9 @@ static int light_read(char *p)
 	int len = 0;
 	int status = 0;
 
-	if (!light_supported) {
+	if (!tp_features.light) {
 		len += sprintf(p + len, "status:\t\tnot supported\n");
-	} else if (!light_status_supported) {
+	} else if (!tp_features.light_status) {
 		len += sprintf(p + len, "status:\t\tunknown\n");
 		len += sprintf(p + len, "commands:\ton, off\n");
 	} else {
@@ -1106,7 +1098,7 @@ static int light_write(char *buf)
 	char *cmd;
 	int success;
 
-	if (!light_supported)
+	if (!tp_features.light)
 		return -ENODEV;
 
 	while ((cmd = next_cmd(&buf))) {
@@ -1251,11 +1243,6 @@ static struct ibm_struct dock_driver_data[2] = {
  */
 
 #ifdef CONFIG_THINKPAD_ACPI_BAY
-static int bay_status_supported;
-static int bay_status2_supported;
-static int bay_eject_supported;
-static int bay_eject2_supported;
-
 IBM_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST",	/* 570 */
 	   "\\_SB.PCI0.IDE0.IDES.IDSM",	/* 600e/x, 770e, 770x */
 	   "\\_SB.PCI0.SATA.SCND.MSTR",	/* T60, X60, Z60 */
@@ -1282,25 +1269,25 @@ static int __init bay_init(struct ibm_init_struct *iibm)
 	if (bay2_handle)
 		IBM_HANDLE_INIT(bay2_ej);
 
-	bay_status_supported = bay_handle &&
-	    acpi_evalf(bay_handle, NULL, "_STA", "qv");
-	bay_status2_supported = bay2_handle &&
-	    acpi_evalf(bay2_handle, NULL, "_STA", "qv");
+	tp_features.bay_status = bay_handle &&
+		acpi_evalf(bay_handle, NULL, "_STA", "qv");
+	tp_features.bay_status2 = bay2_handle &&
+		acpi_evalf(bay2_handle, NULL, "_STA", "qv");
 
-	bay_eject_supported = bay_handle && bay_ej_handle &&
-	    (strlencmp(bay_ej_path, "_EJ0") == 0 || experimental);
-	bay_eject2_supported = bay2_handle && bay2_ej_handle &&
-	    (strlencmp(bay2_ej_path, "_EJ0") == 0 || experimental);
+	tp_features.bay_eject = bay_handle && bay_ej_handle &&
+		(strlencmp(bay_ej_path, "_EJ0") == 0 || experimental);
+	tp_features.bay_eject2 = bay2_handle && bay2_ej_handle &&
+		(strlencmp(bay2_ej_path, "_EJ0") == 0 || experimental);
 
 	vdbg_printk(TPACPI_DBG_INIT,
 		"bay 1: status %s, eject %s; bay 2: status %s, eject %s\n",
-		str_supported(bay_status_supported),
-		str_supported(bay_eject_supported),
-		str_supported(bay_status2_supported),
-		str_supported(bay_eject2_supported));
+		str_supported(tp_features.bay_status),
+		str_supported(tp_features.bay_eject),
+		str_supported(tp_features.bay_status2),
+		str_supported(tp_features.bay_eject2));
 
-	return (bay_status_supported || bay_eject_supported ||
-		bay_status2_supported || bay_eject2_supported)? 0 : 1;
+	return (tp_features.bay_status || tp_features.bay_eject ||
+		tp_features.bay_status2 || tp_features.bay_eject2)? 0 : 1;
 }
 
 static void bay_notify(struct ibm_struct *ibm, u32 event)
@@ -1317,15 +1304,16 @@ static int bay_read(char *p)
 	int occupied2 = bay_occupied(bay2);
 	int eject, eject2;
 
-	len += sprintf(p + len, "status:\t\t%s\n", bay_status_supported ?
-		       (occupied ? "occupied" : "unoccupied") :
-		       "not supported");
-	if (bay_status2_supported)
+	len += sprintf(p + len, "status:\t\t%s\n",
+		tp_features.bay_status ?
+			(occupied ? "occupied" : "unoccupied") :
+				"not supported");
+	if (tp_features.bay_status2)
 		len += sprintf(p + len, "status2:\t%s\n", occupied2 ?
 			       "occupied" : "unoccupied");
 
-	eject = bay_eject_supported && occupied;
-	eject2 = bay_eject2_supported && occupied2;
+	eject = tp_features.bay_eject && occupied;
+	eject2 = tp_features.bay_eject2 && occupied2;
 
 	if (eject && eject2)
 		len += sprintf(p + len, "commands:\teject, eject2\n");
@@ -1341,14 +1329,14 @@ static int bay_write(char *buf)
 {
 	char *cmd;
 
-	if (!bay_eject_supported && !bay_eject2_supported)
+	if (!tp_features.bay_eject && !tp_features.bay_eject2)
 		return -ENODEV;
 
 	while ((cmd = next_cmd(&buf))) {
-		if (bay_eject_supported && strlencmp(cmd, "eject") == 0) {
+		if (tp_features.bay_eject && strlencmp(cmd, "eject") == 0) {
 			if (!acpi_evalf(bay_ej_handle, NULL, NULL, "vd", 1))
 				return -EIO;
-		} else if (bay_eject2_supported &&
+		} else if (tp_features.bay_eject2 &&
 			   strlencmp(cmd, "eject2") == 0) {
 			if (!acpi_evalf(bay2_ej_handle, NULL, NULL, "vd", 1))
 				return -EIO;
@@ -2188,7 +2176,6 @@ static enum fan_status_access_mode fan_status_access_mode;
 static enum fan_control_access_mode fan_control_access_mode;
 static enum fan_control_commands fan_control_commands;
 
-static int fan_control_status_known;
 static u8 fan_control_initial_status;
 
 static void fan_watchdog_fire(struct work_struct *ignored);
@@ -2210,8 +2197,8 @@ static int __init fan_init(struct ibm_init_struct *iibm)
 	fan_status_access_mode = TPACPI_FAN_NONE;
 	fan_control_access_mode = TPACPI_FAN_WR_NONE;
 	fan_control_commands = 0;
-	fan_control_status_known = 1;
 	fan_watchdog_maxinterval = 0;
+	tp_features.fan_ctrl_status_undef = 0;
 
 	IBM_HANDLE_INIT(fans);
 	IBM_HANDLE_INIT(gfan);
@@ -2248,7 +2235,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)
 				       "fan_init: initial fan status is "
 				       "unknown, assuming it is in auto "
 				       "mode\n");
-				fan_control_status_known = 0;
+				tp_features.fan_ctrl_status_undef = 1;
 			}
 		} else {
 			printk(IBM_ERR
@@ -2411,7 +2398,7 @@ static int fan_set_level(int level)
 		if (!acpi_ec_write(fan_status_offset, level))
 			return -EIO;
 		else
-			fan_control_status_known = 1;
+			tp_features.fan_ctrl_status_undef = 0;
 		break;
 
 	default:
@@ -2438,7 +2425,7 @@ static int fan_set_enable(void)
 		if (!acpi_ec_write(fan_status_offset, s))
 			return -EIO;
 		else
-			fan_control_status_known = 1;
+			tp_features.fan_ctrl_status_undef = 0;
 		break;
 
 	case TPACPI_FAN_WR_ACPI_SFAN:
@@ -2469,7 +2456,7 @@ static int fan_set_disable(void)
 		if (!acpi_ec_write(fan_status_offset, 0x00))
 			return -EIO;
 		else
-			fan_control_status_known = 1;
+			tp_features.fan_ctrl_status_undef = 0;
 		break;
 
 	case TPACPI_FAN_WR_ACPI_SFAN:
@@ -2524,9 +2511,9 @@ static int fan_read(char *p)
 		if ((rc = fan_get_status(&status)) < 0)
 			return rc;
 
-		if (unlikely(!fan_control_status_known)) {
+		if (unlikely(tp_features.fan_ctrl_status_undef)) {
 			if (status != fan_control_initial_status)
-				fan_control_status_known = 1;
+				tp_features.fan_ctrl_status_undef = 0;
 			else
 				/* Return most likely status. In fact, it
 				 * might be the only possible status */
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 8b72061..4d3ab40 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -173,6 +173,22 @@ struct ibm_init_struct {
 	struct ibm_struct *data;
 };
 
+static struct {
+#ifdef CONFIG_THINKPAD_ACPI_BAY
+	u16 bay_status:1;
+	u16 bay_eject:1;
+	u16 bay_status2:1;
+	u16 bay_eject2:1;
+#endif
+	u16 bluetooth:1;
+	u16 hotkey:1;
+	u16 hotkey_mask:1;
+	u16 light:1;
+	u16 light_status:1;
+	u16 wan:1;
+	u16 fan_ctrl_status_undef:1;
+} tp_features;
+
 static struct list_head tpacpi_all_drivers;
 
 static struct ibm_init_struct ibms_init[];
@@ -193,9 +209,6 @@ static int thinkpad_acpi_driver_read(char *p);
  */
 
 #ifdef CONFIG_THINKPAD_ACPI_BAY
-static int bay_status_supported, bay_eject_supported;
-static int bay_status2_supported, bay_eject2_supported;
-
 static acpi_handle bay_handle, bay_ej_handle;
 static acpi_handle bay2_handle, bay2_ej_handle;
 
@@ -220,8 +233,6 @@ static int beep_write(char *buf);
  * Bluetooth subdriver
  */
 
-static int bluetooth_supported;
-
 static int bluetooth_init(struct ibm_init_struct *iibm);
 static int bluetooth_status(void);
 static int bluetooth_read(char *p);
@@ -311,7 +322,6 @@ enum fan_control_commands {
 static enum fan_status_access_mode fan_status_access_mode;
 static enum fan_control_access_mode fan_control_access_mode;
 static enum fan_control_commands fan_control_commands;
-static int fan_control_status_known;
 static u8 fan_control_initial_status;
 static int fan_watchdog_maxinterval;
 
@@ -340,8 +350,6 @@ static int fan_write_cmd_watchdog(const char *cmd, int *rc);
  * Hotkey subdriver
  */
 
-static int hotkey_supported;
-static int hotkey_mask_supported;
 static int hotkey_orig_status;
 static int hotkey_orig_mask;
 
@@ -382,8 +390,6 @@ static int led_write(char *buf);
  * Light (thinklight) subdriver
  */
 
-static int light_supported;
-static int light_status_supported;
 static acpi_handle lght_handle, ledb_handle;
 
 static int light_init(struct ibm_init_struct *iibm);
@@ -453,8 +459,6 @@ static int volume_write(char *buf);
  * Wan subdriver
  */
 
-static int wan_supported;
-
 static int wan_init(struct ibm_init_struct *iibm);
 static int wan_status(void);
 static int wan_read(char *p);
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 058/105] ACPI: thinkpad-acpi: prepare for device model conversion
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Prepare the thinkpad-acpi driver for the conversion to the device
model, by renaming variables and doing other glue work that shall
make the later patches much cleaner.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |  231 +++++++++++++++++++++++-------------------
 drivers/misc/thinkpad_acpi.h |   40 +++++---
 2 files changed, 153 insertions(+), 118 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index e2a1b63..809ec84 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -277,7 +277,7 @@ static int _sta(acpi_handle handle)
  * ACPI device model
  */
 
-static void ibm_handle_init(char *name,
+static void drv_acpi_handle_init(char *name,
 			   acpi_handle *handle, acpi_handle parent,
 			   char **paths, int num_paths, char **path)
 {
@@ -295,40 +295,42 @@ static void ibm_handle_init(char *name,
 	*handle = NULL;
 }
 
-static void dispatch_notify(acpi_handle handle, u32 event, void *data)
+static void dispatch_acpi_notify(acpi_handle handle, u32 event, void *data)
 {
 	struct ibm_struct *ibm = data;
 
-	if (!ibm || !ibm->notify)
+	if (!ibm || !ibm->acpi || !ibm->acpi->notify)
 		return;
 
-	ibm->notify(ibm, event);
+	ibm->acpi->notify(ibm, event);
 }
 
-static int __init setup_notify(struct ibm_struct *ibm)
+static int __init setup_acpi_notify(struct ibm_struct *ibm)
 {
 	acpi_status status;
 	int ret;
 
-	if (!*ibm->handle)
+	BUG_ON(!ibm->acpi);
+
+	if (!*ibm->acpi->handle)
 		return 0;
 
 	dbg_printk(TPACPI_DBG_INIT,
 		"setting up ACPI notify for %s\n", ibm->name);
 
-	ret = acpi_bus_get_device(*ibm->handle, &ibm->device);
+	ret = acpi_bus_get_device(*ibm->acpi->handle, &ibm->acpi->device);
 	if (ret < 0) {
 		printk(IBM_ERR "%s device not present\n", ibm->name);
 		return -ENODEV;
 	}
 
-	acpi_driver_data(ibm->device) = ibm;
-	sprintf(acpi_device_class(ibm->device), "%s/%s",
+	acpi_driver_data(ibm->acpi->device) = ibm;
+	sprintf(acpi_device_class(ibm->acpi->device), "%s/%s",
 		IBM_ACPI_EVENT_PREFIX,
 		ibm->name);
 
-	status = acpi_install_notify_handler(*ibm->handle, ibm->type,
-					     dispatch_notify, ibm);
+	status = acpi_install_notify_handler(*ibm->acpi->handle,
+			ibm->acpi->type, dispatch_acpi_notify, ibm);
 	if (ACPI_FAILURE(status)) {
 		if (status == AE_ALREADY_EXISTS) {
 			printk(IBM_NOTICE "another device driver is already handling %s events\n",
@@ -339,11 +341,11 @@ static int __init setup_notify(struct ibm_struct *ibm)
 		}
 		return -ENODEV;
 	}
-	ibm->flags.notify_installed = 1;
+	ibm->flags.acpi_notify_installed = 1;
 	return 0;
 }
 
-static int __init ibm_device_add(struct acpi_device *device)
+static int __init tpacpi_device_add(struct acpi_device *device)
 {
 	return 0;
 }
@@ -355,24 +357,26 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm)
 	dbg_printk(TPACPI_DBG_INIT,
 		"registering %s as an ACPI driver\n", ibm->name);
 
-	ibm->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL);
-	if (!ibm->driver) {
+	BUG_ON(!ibm->acpi);
+
+	ibm->acpi->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL);
+	if (!ibm->acpi->driver) {
 		printk(IBM_ERR "kzalloc(ibm->driver) failed\n");
 		return -ENOMEM;
 	}
 
-	sprintf(ibm->driver->name, "%s_%s", IBM_NAME, ibm->name);
-	ibm->driver->ids = ibm->hid;
-	ibm->driver->ops.add = &ibm_device_add;
+	sprintf(ibm->acpi->driver->name, "%s_%s", IBM_NAME, ibm->name);
+	ibm->acpi->driver->ids = ibm->acpi->hid;
+	ibm->acpi->driver->ops.add = &tpacpi_device_add;
 
-	ret = acpi_bus_register_driver(ibm->driver);
+	ret = acpi_bus_register_driver(ibm->acpi->driver);
 	if (ret < 0) {
 		printk(IBM_ERR "acpi_bus_register_driver(%s) failed: %d\n",
-		       ibm->hid, ret);
-		kfree(ibm->driver);
-		ibm->driver = NULL;
+		       ibm->acpi->hid, ret);
+		kfree(ibm->acpi->driver);
+		ibm->acpi->driver = NULL;
 	} else if (!ret)
-		ibm->flags.driver_registered = 1;
+		ibm->flags.acpi_driver_registered = 1;
 
 	return ret;
 }
@@ -386,8 +390,8 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm)
  ****************************************************************************
  ****************************************************************************/
 
-static int dispatch_read(char *page, char **start, off_t off, int count,
-			 int *eof, void *data)
+static int dispatch_procfs_read(char *page, char **start, off_t off,
+			int count, int *eof, void *data)
 {
 	struct ibm_struct *ibm = data;
 	int len;
@@ -411,8 +415,9 @@ static int dispatch_read(char *page, char **start, off_t off, int count,
 	return len;
 }
 
-static int dispatch_write(struct file *file, const char __user * userbuf,
-			  unsigned long count, void *data)
+static int dispatch_procfs_write(struct file *file,
+			const char __user * userbuf,
+			unsigned long count, void *data)
 {
 	struct ibm_struct *ibm = data;
 	char *kernbuf;
@@ -508,7 +513,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
 {
 	vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n");
 
-	IBM_HANDLE_INIT(hkey);
+	IBM_ACPIHANDLE_INIT(hkey);
 
 	/* hotkey not supported on 570 */
 	tp_features.hotkey = hkey_handle != NULL;
@@ -545,10 +550,10 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
 	int hkey;
 
 	if (acpi_evalf(hkey_handle, &hkey, "MHKP", "d"))
-		acpi_bus_generate_event(ibm->device, event, hkey);
+		acpi_bus_generate_event(ibm->acpi->device, event, hkey);
 	else {
 		printk(IBM_ERR "unknown hotkey event %d\n", event);
-		acpi_bus_generate_event(ibm->device, event, 0);
+		acpi_bus_generate_event(ibm->acpi->device, event, 0);
 	}
 }
 
@@ -643,15 +648,19 @@ static int hotkey_write(char *buf)
 	return 0;
 }
 
+static struct tp_acpi_drv_struct ibm_hotkey_acpidriver = {
+	.hid = IBM_HKEY_HID,
+	.notify = hotkey_notify,
+	.handle = &hkey_handle,
+	.type = ACPI_DEVICE_NOTIFY,
+};
+
 static struct ibm_struct hotkey_driver_data = {
 	.name = "hotkey",
-	.hid = IBM_HKEY_HID,
 	.read = hotkey_read,
 	.write = hotkey_write,
 	.exit = hotkey_exit,
-	.notify = hotkey_notify,
-	.handle = &hkey_handle,
-	.type = ACPI_DEVICE_NOTIFY,
+	.acpi = &ibm_hotkey_acpidriver,
 };
 
 /*************************************************************************
@@ -662,7 +671,7 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
 {
 	vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n");
 
-	IBM_HANDLE_INIT(hkey);
+	IBM_ACPIHANDLE_INIT(hkey);
 
 	/* bluetooth not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
 	   G4x, R30, R31, R40e, R50e, T20-22, X20-21 */
@@ -742,7 +751,7 @@ static int __init wan_init(struct ibm_init_struct *iibm)
 {
 	vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n");
 
-	IBM_HANDLE_INIT(hkey);
+	IBM_ACPIHANDLE_INIT(hkey);
 
 	tp_features.wan = hkey_handle &&
 			  acpi_evalf(hkey_handle, NULL, "GWAN", "qv");
@@ -835,8 +844,8 @@ static int __init video_init(struct ibm_init_struct *iibm)
 
 	vdbg_printk(TPACPI_DBG_INIT, "initializing video subdriver\n");
 
-	IBM_HANDLE_INIT(vid);
-	IBM_HANDLE_INIT(vid2);
+	IBM_ACPIHANDLE_INIT(vid);
+	IBM_ACPIHANDLE_INIT(vid2);
 
 	if (vid2_handle && acpi_evalf(NULL, &ivga, "\\IVGA", "d") && ivga)
 		/* G41, assume IVGA doesn't change */
@@ -1053,9 +1062,9 @@ static int __init light_init(struct ibm_init_struct *iibm)
 {
 	vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n");
 
-	IBM_HANDLE_INIT(ledb);
-	IBM_HANDLE_INIT(lght);
-	IBM_HANDLE_INIT(cmos);
+	IBM_ACPIHANDLE_INIT(ledb);
+	IBM_ACPIHANDLE_INIT(lght);
+	IBM_ACPIHANDLE_INIT(cmos);
 
 	/* light not supported on 570, 600e/x, 770e, 770x, G4x, R30, R31 */
 	tp_features.light = (cmos_handle || lght_handle) && !ledb_handle;
@@ -1148,8 +1157,8 @@ static int __init dock_init(struct ibm_init_struct *iibm)
 {
 	vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver\n");
 
-	IBM_HANDLE_INIT(dock);
-	IBM_HANDLE_INIT(pci);
+	IBM_ACPIHANDLE_INIT(dock);
+	IBM_ACPIHANDLE_INIT(pci);
 
 	vdbg_printk(TPACPI_DBG_INIT, "dock is %s\n",
 		str_supported(dock_handle != NULL));
@@ -1160,22 +1169,22 @@ static int __init dock_init(struct ibm_init_struct *iibm)
 static void dock_notify(struct ibm_struct *ibm, u32 event)
 {
 	int docked = dock_docked();
-	int pci = ibm->hid && strstr(ibm->hid, IBM_PCI_HID);
+	int pci = ibm->acpi->hid && strstr(ibm->acpi->hid, IBM_PCI_HID);
 
 	if (event == 1 && !pci)	/* 570 */
-		acpi_bus_generate_event(ibm->device, event, 1);	/* button */
+		acpi_bus_generate_event(ibm->acpi->device, event, 1);	/* button */
 	else if (event == 1 && pci)	/* 570 */
-		acpi_bus_generate_event(ibm->device, event, 3);	/* dock */
+		acpi_bus_generate_event(ibm->acpi->device, event, 3);	/* dock */
 	else if (event == 3 && docked)
-		acpi_bus_generate_event(ibm->device, event, 1);	/* button */
+		acpi_bus_generate_event(ibm->acpi->device, event, 1);	/* button */
 	else if (event == 3 && !docked)
-		acpi_bus_generate_event(ibm->device, event, 2);	/* undock */
+		acpi_bus_generate_event(ibm->acpi->device, event, 2);	/* undock */
 	else if (event == 0 && docked)
-		acpi_bus_generate_event(ibm->device, event, 3);	/* dock */
+		acpi_bus_generate_event(ibm->acpi->device, event, 3);	/* dock */
 	else {
 		printk(IBM_ERR "unknown dock event %d, status %d\n",
 		       event, _sta(dock_handle));
-		acpi_bus_generate_event(ibm->device, event, 0);	/* unknown */
+		acpi_bus_generate_event(ibm->acpi->device, event, 0);	/* unknown */
 	}
 }
 
@@ -1218,17 +1227,13 @@ static int dock_write(char *buf)
 	return 0;
 }
 
-static struct ibm_struct dock_driver_data[2] = {
+static struct tp_acpi_drv_struct ibm_dock_acpidriver[2] = {
 	{
-	 .name = "dock",
-	 .read = dock_read,
-	 .write = dock_write,
 	 .notify = dock_notify,
 	 .handle = &dock_handle,
 	 .type = ACPI_SYSTEM_NOTIFY,
 	},
 	{
-	 .name = "dock",
 	 .hid = IBM_PCI_HID,
 	 .notify = dock_notify,
 	 .handle = &pci_handle,
@@ -1236,6 +1241,19 @@ static struct ibm_struct dock_driver_data[2] = {
 	},
 };
 
+static struct ibm_struct dock_driver_data[2] = {
+	{
+	 .name = "dock",
+	 .read = dock_read,
+	 .write = dock_write,
+	 .acpi = &ibm_dock_acpidriver[0],
+	},
+	{
+	 .name = "dock",
+	 .acpi = &ibm_dock_acpidriver[1],
+	},
+};
+
 #endif /* CONFIG_THINKPAD_ACPI_DOCK */
 
 /*************************************************************************
@@ -1262,12 +1280,12 @@ static int __init bay_init(struct ibm_init_struct *iibm)
 {
 	vdbg_printk(TPACPI_DBG_INIT, "initializing bay subdriver\n");
 
-	IBM_HANDLE_INIT(bay);
+	IBM_ACPIHANDLE_INIT(bay);
 	if (bay_handle)
-		IBM_HANDLE_INIT(bay_ej);
-	IBM_HANDLE_INIT(bay2);
+		IBM_ACPIHANDLE_INIT(bay_ej);
+	IBM_ACPIHANDLE_INIT(bay2);
 	if (bay2_handle)
-		IBM_HANDLE_INIT(bay2_ej);
+		IBM_ACPIHANDLE_INIT(bay2_ej);
 
 	tp_features.bay_status = bay_handle &&
 		acpi_evalf(bay_handle, NULL, "_STA", "qv");
@@ -1292,7 +1310,7 @@ static int __init bay_init(struct ibm_init_struct *iibm)
 
 static void bay_notify(struct ibm_struct *ibm, u32 event)
 {
-	acpi_bus_generate_event(ibm->device, event, 0);
+	acpi_bus_generate_event(ibm->acpi->device, event, 0);
 }
 
 #define bay_occupied(b) (_sta(b##_handle) & 1)
@@ -1347,13 +1365,17 @@ static int bay_write(char *buf)
 	return 0;
 }
 
+static struct tp_acpi_drv_struct ibm_bay_acpidriver = {
+	.notify = bay_notify,
+	.handle = &bay_handle,
+	.type = ACPI_SYSTEM_NOTIFY,
+};
+
 static struct ibm_struct bay_driver_data = {
 	.name = "bay",
 	.read = bay_read,
 	.write = bay_write,
-	.notify = bay_notify,
-	.handle = &bay_handle,
-	.type = ACPI_SYSTEM_NOTIFY,
+	.acpi = &ibm_bay_acpidriver,
 };
 
 #endif /* CONFIG_THINKPAD_ACPI_BAY */
@@ -1367,7 +1389,7 @@ static int __init cmos_init(struct ibm_init_struct *iibm)
 	vdbg_printk(TPACPI_DBG_INIT,
 		"initializing cmos commands subdriver\n");
 
-	IBM_HANDLE_INIT(cmos);
+	IBM_ACPIHANDLE_INIT(cmos);
 
 	vdbg_printk(TPACPI_DBG_INIT, "cmos commands are %s\n",
 		str_supported(cmos_handle != NULL));
@@ -1441,7 +1463,7 @@ static int __init led_init(struct ibm_init_struct *iibm)
 {
 	vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n");
 
-	IBM_HANDLE_INIT(led);
+	IBM_ACPIHANDLE_INIT(led);
 
 	if (!led_handle)
 		/* led not supported on R30, R31 */
@@ -1566,7 +1588,7 @@ static int __init beep_init(struct ibm_init_struct *iibm)
 {
 	vdbg_printk(TPACPI_DBG_INIT, "initializing beep subdriver\n");
 
-	IBM_HANDLE_INIT(beep);
+	IBM_ACPIHANDLE_INIT(beep);
 
 	vdbg_printk(TPACPI_DBG_INIT, "beep is %s\n",
 		str_supported(beep_handle != NULL));
@@ -2200,9 +2222,9 @@ static int __init fan_init(struct ibm_init_struct *iibm)
 	fan_watchdog_maxinterval = 0;
 	tp_features.fan_ctrl_status_undef = 0;
 
-	IBM_HANDLE_INIT(fans);
-	IBM_HANDLE_INIT(gfan);
-	IBM_HANDLE_INIT(sfan);
+	IBM_ACPIHANDLE_INIT(fans);
+	IBM_ACPIHANDLE_INIT(gfan);
+	IBM_ACPIHANDLE_INIT(sfan);
 
 	if (gfan_handle) {
 		/* 570, 600e/x, 770e, 770x */
@@ -2728,22 +2750,24 @@ static int __init ibm_init(struct ibm_init_struct *iibm)
 		ibm->flags.init_called = 1;
 	}
 
-	if (ibm->hid) {
-		ret = register_tpacpi_subdriver(ibm);
-		if (ret)
-			goto err_out;
-	}
+	if (ibm->acpi) {
+		if (ibm->acpi->hid) {
+			ret = register_tpacpi_subdriver(ibm);
+			if (ret)
+				goto err_out;
+		}
 
-	if (ibm->notify) {
-		ret = setup_notify(ibm);
-		if (ret == -ENODEV) {
-			printk(IBM_NOTICE "disabling subdriver %s\n",
-				ibm->name);
-			ret = 0;
-			goto err_out;
+		if (ibm->acpi->notify) {
+			ret = setup_acpi_notify(ibm);
+			if (ret == -ENODEV) {
+				printk(IBM_NOTICE "disabling subdriver %s\n",
+					ibm->name);
+				ret = 0;
+				goto err_out;
+			}
+			if (ret < 0)
+				goto err_out;
 		}
-		if (ret < 0)
-			goto err_out;
 	}
 
 	dbg_printk(TPACPI_DBG_INIT,
@@ -2761,9 +2785,9 @@ static int __init ibm_init(struct ibm_init_struct *iibm)
 		}
 		entry->owner = THIS_MODULE;
 		entry->data = ibm;
-		entry->read_proc = &dispatch_read;
+		entry->read_proc = &dispatch_procfs_read;
 		if (ibm->write)
-			entry->write_proc = &dispatch_write;
+			entry->write_proc = &dispatch_procfs_write;
 		ibm->flags.proc_created = 1;
 	}
 
@@ -2786,12 +2810,15 @@ static void ibm_exit(struct ibm_struct *ibm)
 
 	list_del_init(&ibm->all_drivers);
 
-	if (ibm->flags.notify_installed) {
+	if (ibm->flags.acpi_notify_installed) {
 		dbg_printk(TPACPI_DBG_EXIT,
 			"%s: acpi_remove_notify_handler\n", ibm->name);
-		acpi_remove_notify_handler(*ibm->handle, ibm->type,
-					   dispatch_notify);
-		ibm->flags.notify_installed = 0;
+		BUG_ON(!ibm->acpi);
+		acpi_remove_notify_handler(*ibm->acpi->handle,
+					   ibm->acpi->type,
+					   dispatch_acpi_notify);
+		ibm->flags.acpi_notify_installed = 0;
+		ibm->flags.acpi_notify_installed = 0;
 	}
 
 	if (ibm->flags.proc_created) {
@@ -2801,13 +2828,14 @@ static void ibm_exit(struct ibm_struct *ibm)
 		ibm->flags.proc_created = 0;
 	}
 
-	if (ibm->flags.driver_registered) {
+	if (ibm->flags.acpi_driver_registered) {
 		dbg_printk(TPACPI_DBG_EXIT,
 			"%s: acpi_bus_unregister_driver\n", ibm->name);
-		acpi_bus_unregister_driver(ibm->driver);
-		kfree(ibm->driver);
-		ibm->driver = NULL;
-		ibm->flags.driver_registered = 0;
+		BUG_ON(!ibm->acpi);
+		acpi_bus_unregister_driver(ibm->acpi->driver);
+		kfree(ibm->acpi->driver);
+		ibm->acpi->driver = NULL;
+		ibm->flags.acpi_driver_registered = 0;
 	}
 
 	if (ibm->flags.init_called && ibm->exit) {
@@ -2860,7 +2888,7 @@ static int __init probe_for_thinkpad(void)
 	is_thinkpad = dmi_name_in_vendors("ThinkPad");
 
 	/* ec is required because many other handles are relative to it */
-	IBM_HANDLE_INIT(ec);
+	IBM_ACPIHANDLE_INIT(ec);
 	if (!ec_handle) {
 		if (is_thinkpad)
 			printk(IBM_ERR
@@ -3016,12 +3044,12 @@ static int __init thinkpad_acpi_module_init(void)
 		return ret;
 
 	ibm_thinkpad_ec_found = check_dmi_for_ec();
-	IBM_HANDLE_INIT(ecrd);
-	IBM_HANDLE_INIT(ecwr);
+	IBM_ACPIHANDLE_INIT(ecrd);
+	IBM_ACPIHANDLE_INIT(ecwr);
 
-	proc_dir = proc_mkdir(IBM_DIR, acpi_root_dir);
+	proc_dir = proc_mkdir(IBM_PROC_DIR, acpi_root_dir);
 	if (!proc_dir) {
-		printk(IBM_ERR "unable to create proc dir %s", IBM_DIR);
+		printk(IBM_ERR "unable to create proc dir " IBM_PROC_DIR);
 		thinkpad_acpi_module_exit();
 		return -ENODEV;
 	}
@@ -3053,10 +3081,9 @@ static void thinkpad_acpi_module_exit(void)
 	dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n");
 
 	if (proc_dir)
-		remove_proc_entry(IBM_DIR, acpi_root_dir);
+		remove_proc_entry(IBM_PROC_DIR, acpi_root_dir);
 
-	if (ibm_thinkpad_ec_found)
-		kfree(ibm_thinkpad_ec_found);
+	kfree(ibm_thinkpad_ec_found);
 }
 
 module_init(thinkpad_acpi_module_init);
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 4d3ab40..529528c 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -52,8 +52,9 @@
 #define IBM_DESC "ThinkPad ACPI Extras"
 #define IBM_FILE "thinkpad_acpi"
 #define IBM_URL "http://ibm-acpi.sf.net/"
+#define IBM_MAIL "ibm-acpi-devel@lists.sourceforge.net"
 
-#define IBM_DIR "ibm"
+#define IBM_PROC_DIR "ibm"
 #define IBM_ACPI_EVENT_PREFIX "ibm"
 
 #define IBM_LOG IBM_FILE ": "
@@ -108,20 +109,21 @@ static acpi_handle ec_handle;			/* EC */
 static acpi_handle ecrd_handle, ecwr_handle;	/* 570 EC access */
 static acpi_handle cmos_handle, hkey_handle;	/* basic thinkpad handles */
 
-static void ibm_handle_init(char *name,
+static void drv_acpi_handle_init(char *name,
 		   acpi_handle *handle, acpi_handle parent,
 		   char **paths, int num_paths, char **path);
-#define IBM_HANDLE_INIT(object)						\
-	ibm_handle_init(#object, &object##_handle, *object##_parent,	\
+#define IBM_ACPIHANDLE_INIT(object)						\
+	drv_acpi_handle_init(#object, &object##_handle, *object##_parent,	\
 		object##_paths, ARRAY_SIZE(object##_paths), &object##_path)
 
 /* procfs support */
 static struct proc_dir_entry *proc_dir;
 
 /* procfs helpers */
-static int dispatch_read(char *page, char **start, off_t off, int count,
-		int *eof, void *data);
-static int dispatch_write(struct file *file, const char __user * userbuf,
+static int dispatch_procfs_read(char *page, char **start, off_t off,
+		int count, int *eof, void *data);
+static int dispatch_procfs_write(struct file *file,
+		const char __user * userbuf,
 		unsigned long count, void *data);
 static char *next_cmd(char **cmds);
 
@@ -140,28 +142,34 @@ static void thinkpad_acpi_module_exit(void);
  * Subdrivers
  */
 
-struct ibm_struct {
-	char *name;
+struct ibm_struct;
 
+struct tp_acpi_drv_struct {
 	char *hid;
 	struct acpi_driver *driver;
 
-	int (*read) (char *);
-	int (*write) (char *);
-	void (*exit) (void);
-
 	void (*notify) (struct ibm_struct *, u32);
 	acpi_handle *handle;
-	int type;
+	u32 type;
 	struct acpi_device *device;
+};
+
+struct ibm_struct {
+	char *name;
+
+	int (*read) (char *);
+	int (*write) (char *);
+	void (*exit) (void);
 
 	struct list_head all_drivers;
 
+	struct tp_acpi_drv_struct *acpi;
+
 	struct {
-		u8 driver_registered:1;
+		u8 acpi_driver_registered:1;
+		u8 acpi_notify_installed:1;
 		u8 proc_created:1;
 		u8 init_called:1;
-		u8 notify_installed:1;
 		u8 experimental:1;
 	} flags;
 };
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 059/105] ACPI: thinkpad-acpi: mark acpi helper functions __must_check
@ 2007-04-29  4:50       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:50 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Mark acpi_evalf and friends __must_check.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.h |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 529528c..1b4cd16 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -97,11 +97,11 @@ static const char *str_supported(int is_supported);
 #define IBM_PCI_HID     "PNP0A03"
 
 /* ACPI helpers */
-static int acpi_evalf(acpi_handle handle,
+static int __must_check acpi_evalf(acpi_handle handle,
 		      void *res, char *method, char *fmt, ...);
-static int acpi_ec_read(int i, u8 * p);
-static int acpi_ec_write(int i, u8 v);
-static int _sta(acpi_handle handle);
+static int __must_check acpi_ec_read(int i, u8 * p);
+static int __must_check acpi_ec_write(int i, u8 v);
+static int __must_check _sta(acpi_handle handle);
 
 /* ACPI handles */
 static acpi_handle root_handle;			/* root namespace */
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 060/105] ACPI: thinkpad-acpi: clean up hotkey subdriver
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Cleanup hotkey subdriver code.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |   46 ++++++++++++++++++++++++++---------------
 1 files changed, 29 insertions(+), 17 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 809ec84..344eb55 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -511,6 +511,8 @@ static int hotkey_orig_mask;
 
 static int __init hotkey_init(struct ibm_init_struct *iibm)
 {
+	int res;
+
 	vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n");
 
 	IBM_ACPIHANDLE_INIT(hkey);
@@ -530,8 +532,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
 		vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n",
 			str_supported(tp_features.hotkey_mask));
 
-		if (!hotkey_get(&hotkey_orig_status, &hotkey_orig_mask))
-			return -ENODEV;
+		res = hotkey_get(&hotkey_orig_status, &hotkey_orig_mask);
+		if (res)
+			return res;
 	}
 
 	return (tp_features.hotkey)? 0 : 1;
@@ -539,9 +542,13 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
 
 static void hotkey_exit(void)
 {
+	int res;
+
 	if (tp_features.hotkey) {
 		dbg_printk(TPACPI_DBG_EXIT, "restoring original hotkey mask\n");
-		hotkey_set(hotkey_orig_status, hotkey_orig_mask);
+		res = hotkey_set(hotkey_orig_status, hotkey_orig_mask);
+		if (res)
+			printk(IBM_ERR "failed to restore hotkey to BIOS defaults\n");
 	}
 }
 
@@ -560,13 +567,13 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
 static int hotkey_get(int *status, int *mask)
 {
 	if (!acpi_evalf(hkey_handle, status, "DHKC", "d"))
-		return 0;
+		return -EIO;
 
 	if (tp_features.hotkey_mask)
 		if (!acpi_evalf(hkey_handle, mask, "DHKN", "d"))
-			return 0;
+			return -EIO;
 
-	return 1;
+	return 0;
 }
 
 static int hotkey_set(int status, int mask)
@@ -574,22 +581,22 @@ static int hotkey_set(int status, int mask)
 	int i;
 
 	if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status))
-		return 0;
+		return -EIO;
 
 	if (tp_features.hotkey_mask)
 		for (i = 0; i < 32; i++) {
 			int bit = ((1 << i) & mask) != 0;
 			if (!acpi_evalf(hkey_handle,
 					NULL, "MHKM", "vdd", i + 1, bit))
-				return 0;
+				return -EIO;
 		}
 
-	return 1;
+	return 0;
 }
 
 static int hotkey_read(char *p)
 {
-	int status, mask;
+	int res, status, mask;
 	int len = 0;
 
 	if (!tp_features.hotkey) {
@@ -597,8 +604,9 @@ static int hotkey_read(char *p)
 		return len;
 	}
 
-	if (!hotkey_get(&status, &mask))
-		return -EIO;
+	res = hotkey_get(&status, &mask);
+	if (res)
+		return res;
 
 	len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0));
 	if (tp_features.hotkey_mask) {
@@ -615,15 +623,16 @@ static int hotkey_read(char *p)
 
 static int hotkey_write(char *buf)
 {
-	int status, mask;
+	int res, status, mask;
 	char *cmd;
 	int do_cmd = 0;
 
 	if (!tp_features.hotkey)
 		return -ENODEV;
 
-	if (!hotkey_get(&status, &mask))
-		return -EIO;
+	res = hotkey_get(&status, &mask);
+	if (res)
+		return res;
 
 	while ((cmd = next_cmd(&buf))) {
 		if (strlencmp(cmd, "enable") == 0) {
@@ -642,8 +651,11 @@ static int hotkey_write(char *buf)
 		do_cmd = 1;
 	}
 
-	if (do_cmd && !hotkey_set(status, mask))
-		return -EIO;
+	if (do_cmd) {
+		res = hotkey_set(status, mask);
+		if (res)
+			return res;
+	}
 
 	return 0;
 }
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 061/105] ACPI: thinkpad-acpi: cleanup bluetooth and wan for sysfs conversion
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Prepare bluetooth and wan driver code to be more easily hooked into sysfs
helpers, by separating the procfs logic from the device attribute handling.

These changes also remove the entries from procfs on notebooks without the
bluetooth/wan hardware installed.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |  130 +++++++++++++++++++++++++++++-------------
 drivers/misc/thinkpad_acpi.h |   20 ++++++-
 2 files changed, 108 insertions(+), 42 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 344eb55..a77368f 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -681,6 +681,8 @@ static struct ibm_struct hotkey_driver_data = {
 
 static int __init bluetooth_init(struct ibm_init_struct *iibm)
 {
+	int status = 0;
+
 	vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n");
 
 	IBM_ACPIHANDLE_INIT(hkey);
@@ -688,36 +690,65 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
 	/* bluetooth not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
 	   G4x, R30, R31, R40e, R50e, T20-22, X20-21 */
 	tp_features.bluetooth = hkey_handle &&
-	    acpi_evalf(hkey_handle, NULL, "GBDC", "qv");
+	    acpi_evalf(hkey_handle, &status, "GBDC", "qd");
 
-	vdbg_printk(TPACPI_DBG_INIT, "bluetooth is %s\n",
-		str_supported(tp_features.bluetooth));
+	vdbg_printk(TPACPI_DBG_INIT, "bluetooth is %s, status 0x%02x\n",
+		str_supported(tp_features.bluetooth),
+		status);
+
+	if (tp_features.bluetooth &&
+	    !(status & TP_ACPI_BLUETOOTH_HWPRESENT)) {
+		/* no bluetooth hardware present in system */
+		tp_features.bluetooth = 0;
+		dbg_printk(TPACPI_DBG_INIT,
+			   "bluetooth hardware not installed\n");
+	}
 
 	return (tp_features.bluetooth)? 0 : 1;
 }
 
-static int bluetooth_status(void)
+static int bluetooth_get_radiosw(void)
 {
 	int status;
 
-	if (!tp_features.bluetooth ||
-	    !acpi_evalf(hkey_handle, &status, "GBDC", "d"))
-		status = 0;
+	if (!tp_features.bluetooth)
+		return -ENODEV;
 
-	return status;
+	if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
+		return -EIO;
+
+	return ((status & TP_ACPI_BLUETOOTH_RADIOSSW) != 0);
+}
+
+static int bluetooth_set_radiosw(int radio_on)
+{
+	int status;
+
+	if (!tp_features.bluetooth)
+		return -ENODEV;
+
+	if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
+		return -EIO;
+	if (radio_on)
+		status |= TP_ACPI_BLUETOOTH_RADIOSSW;
+	else
+		status &= ~TP_ACPI_BLUETOOTH_RADIOSSW;
+	if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
+		return -EIO;
+
+	return 0;
 }
 
 static int bluetooth_read(char *p)
 {
 	int len = 0;
-	int status = bluetooth_status();
+	int status = bluetooth_get_radiosw();
 
 	if (!tp_features.bluetooth)
 		len += sprintf(p + len, "status:\t\tnot supported\n");
-	else if (!(status & 1))
-		len += sprintf(p + len, "status:\t\tnot installed\n");
 	else {
-		len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 1));
+		len += sprintf(p + len, "status:\t\t%s\n",
+				(status)? "enabled" : "disabled");
 		len += sprintf(p + len, "commands:\tenable, disable\n");
 	}
 
@@ -726,26 +757,20 @@ static int bluetooth_read(char *p)
 
 static int bluetooth_write(char *buf)
 {
-	int status = bluetooth_status();
 	char *cmd;
-	int do_cmd = 0;
 
 	if (!tp_features.bluetooth)
 		return -ENODEV;
 
 	while ((cmd = next_cmd(&buf))) {
 		if (strlencmp(cmd, "enable") == 0) {
-			status |= 2;
+			bluetooth_set_radiosw(1);
 		} else if (strlencmp(cmd, "disable") == 0) {
-			status &= ~2;
+			bluetooth_set_radiosw(0);
 		} else
 			return -EINVAL;
-		do_cmd = 1;
 	}
 
-	if (do_cmd && !acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
-		return -EIO;
-
 	return 0;
 }
 
@@ -761,41 +786,72 @@ static struct ibm_struct bluetooth_driver_data = {
 
 static int __init wan_init(struct ibm_init_struct *iibm)
 {
+	int status = 0;
+
 	vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n");
 
 	IBM_ACPIHANDLE_INIT(hkey);
 
 	tp_features.wan = hkey_handle &&
-			  acpi_evalf(hkey_handle, NULL, "GWAN", "qv");
+	    acpi_evalf(hkey_handle, &status, "GWAN", "qd");
 
-	vdbg_printk(TPACPI_DBG_INIT, "wan is %s\n",
-		str_supported(tp_features.wan));
+	vdbg_printk(TPACPI_DBG_INIT, "wan is %s, status 0x%02x\n",
+		str_supported(tp_features.wan),
+		status);
+
+	if (tp_features.wan &&
+	    !(status & TP_ACPI_WANCARD_HWPRESENT)) {
+		/* no wan hardware present in system */
+		tp_features.wan = 0;
+		dbg_printk(TPACPI_DBG_INIT,
+			   "wan hardware not installed\n");
+	}
 
 	return (tp_features.wan)? 0 : 1;
 }
 
-static int wan_status(void)
+static int wan_get_radiosw(void)
 {
 	int status;
 
-	if (!tp_features.wan ||
-	    !acpi_evalf(hkey_handle, &status, "GWAN", "d"))
-		status = 0;
+	if (!tp_features.wan)
+		return -ENODEV;
 
-	return status;
+	if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
+		return -EIO;
+
+	return ((status & TP_ACPI_WANCARD_RADIOSSW) != 0);
+}
+
+static int wan_set_radiosw(int radio_on)
+{
+	int status;
+
+	if (!tp_features.wan)
+		return -ENODEV;
+
+	if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
+		return -EIO;
+	if (radio_on)
+		status |= TP_ACPI_WANCARD_RADIOSSW;
+	else
+		status &= ~TP_ACPI_WANCARD_RADIOSSW;
+	if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
+		return -EIO;
+
+	return 0;
 }
 
 static int wan_read(char *p)
 {
 	int len = 0;
-	int status = wan_status();
+	int status = wan_get_radiosw();
 
 	if (!tp_features.wan)
 		len += sprintf(p + len, "status:\t\tnot supported\n");
-	else if (!(status & 1))
-		len += sprintf(p + len, "status:\t\tnot installed\n");
 	else {
-		len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 1));
+		len += sprintf(p + len, "status:\t\t%s\n",
+				(status)? "enabled" : "disabled");
 		len += sprintf(p + len, "commands:\tenable, disable\n");
 	}
 
@@ -804,26 +860,20 @@ static int wan_read(char *p)
 
 static int wan_write(char *buf)
 {
-	int status = wan_status();
 	char *cmd;
-	int do_cmd = 0;
 
 	if (!tp_features.wan)
 		return -ENODEV;
 
 	while ((cmd = next_cmd(&buf))) {
 		if (strlencmp(cmd, "enable") == 0) {
-			status |= 2;
+			wan_set_radiosw(1);
 		} else if (strlencmp(cmd, "disable") == 0) {
-			status &= ~2;
+			wan_set_radiosw(0);
 		} else
 			return -EINVAL;
-		do_cmd = 1;
 	}
 
-	if (do_cmd && !acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
-		return -EIO;
-
 	return 0;
 }
 
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 1b4cd16..e06bad5 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -241,8 +241,16 @@ static int beep_write(char *buf);
  * Bluetooth subdriver
  */
 
+enum {
+	/* ACPI GBDC/SBDC bits */
+	TP_ACPI_BLUETOOTH_HWPRESENT	= 0x01,	/* Bluetooth hw available */
+	TP_ACPI_BLUETOOTH_RADIOSSW	= 0x02,	/* Bluetooth radio enabled */
+	TP_ACPI_BLUETOOTH_UNK		= 0x04,	/* unknown function */
+};
+
 static int bluetooth_init(struct ibm_init_struct *iibm);
-static int bluetooth_status(void);
+static int bluetooth_get_radiosw(void);
+static int bluetooth_set_radiosw(int radio_on);
 static int bluetooth_read(char *p);
 static int bluetooth_write(char *buf);
 
@@ -467,8 +475,16 @@ static int volume_write(char *buf);
  * Wan subdriver
  */
 
+enum {
+	/* ACPI GWAN/SWAN bits */
+	TP_ACPI_WANCARD_HWPRESENT	= 0x01,	/* Wan hw available */
+	TP_ACPI_WANCARD_RADIOSSW	= 0x02,	/* Wan radio enabled */
+	TP_ACPI_WANCARD_UNK		= 0x04,	/* unknown function */
+};
+
 static int wan_init(struct ibm_init_struct *iibm);
-static int wan_status(void);
+static int wan_get_radiosw(void);
+static int wan_set_radiosw(int radio_on);
 static int wan_read(char *p);
 static int wan_write(char *buf);
 
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 062/105] ACPI: thinkpad-acpi: cleanup video subdriver
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Cleanup video subdriver for sysfs conversion, and properly check
result status of acpi_evalf.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |  262 ++++++++++++++++++++++++++++--------------
 drivers/misc/thinkpad_acpi.h |   25 +++-
 2 files changed, 197 insertions(+), 90 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index a77368f..19c14bb 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -935,111 +935,194 @@ static int __init video_init(struct ibm_init_struct *iibm)
 
 static void video_exit(void)
 {
-	dbg_printk(TPACPI_DBG_EXIT, "restoring original video autoswitch mode\n");
-	acpi_evalf(vid_handle, NULL, "_DOS", "vd", video_orig_autosw);
+	dbg_printk(TPACPI_DBG_EXIT,
+		   "restoring original video autoswitch mode\n");
+	if (video_autosw_set(video_orig_autosw))
+		printk(IBM_ERR "error while trying to restore original "
+			"video autoswitch mode\n");
 }
 
-static int video_status(void)
+static int video_outputsw_get(void)
 {
 	int status = 0;
 	int i;
 
-	if (video_supported == TPACPI_VIDEO_570) {
-		if (acpi_evalf(NULL, &i, "\\_SB.PHS", "dd", 0x87))
-			status = i & 3;
-	} else if (video_supported == TPACPI_VIDEO_770) {
-		if (acpi_evalf(NULL, &i, "\\VCDL", "d"))
-			status |= 0x01 * i;
-		if (acpi_evalf(NULL, &i, "\\VCDC", "d"))
-			status |= 0x02 * i;
-	} else if (video_supported == TPACPI_VIDEO_NEW) {
-		acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1);
-		if (acpi_evalf(NULL, &i, "\\VCDC", "d"))
-			status |= 0x02 * i;
-
-		acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0);
-		if (acpi_evalf(NULL, &i, "\\VCDL", "d"))
-			status |= 0x01 * i;
-		if (acpi_evalf(NULL, &i, "\\VCDD", "d"))
-			status |= 0x08 * i;
+	switch (video_supported) {
+	case TPACPI_VIDEO_570:
+		if (!acpi_evalf(NULL, &i, "\\_SB.PHS", "dd",
+				 TP_ACPI_VIDEO_570_PHSCMD))
+			return -EIO;
+		status = i & TP_ACPI_VIDEO_570_PHSMASK;
+		break;
+	case TPACPI_VIDEO_770:
+		if (!acpi_evalf(NULL, &i, "\\VCDL", "d"))
+			return -EIO;
+		if (i)
+			status |= TP_ACPI_VIDEO_S_LCD;
+		if (!acpi_evalf(NULL, &i, "\\VCDC", "d"))
+			return -EIO;
+		if (i)
+			status |= TP_ACPI_VIDEO_S_CRT;
+		break;
+	case TPACPI_VIDEO_NEW:
+		if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1) ||
+		    !acpi_evalf(NULL, &i, "\\VCDC", "d"))
+			return -EIO;
+		if (i)
+			status |= TP_ACPI_VIDEO_S_CRT;
+
+		if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0) ||
+		    !acpi_evalf(NULL, &i, "\\VCDL", "d"))
+			return -EIO;
+		if (i)
+			status |= TP_ACPI_VIDEO_S_LCD;
+		if (!acpi_evalf(NULL, &i, "\\VCDD", "d"))
+			return -EIO;
+		if (i)
+			status |= TP_ACPI_VIDEO_S_DVI;
+		break;
+	default:
+		return -ENOSYS;
 	}
 
 	return status;
 }
 
-static int video_autosw(void)
+static int video_outputsw_set(int status)
 {
-	int autosw = 0;
+	int autosw;
+	int res = 0;
 
-	if (video_supported == TPACPI_VIDEO_570)
-		acpi_evalf(vid_handle, &autosw, "SWIT", "d");
-	else if (video_supported == TPACPI_VIDEO_770 ||
-		 video_supported == TPACPI_VIDEO_NEW)
-		acpi_evalf(vid_handle, &autosw, "^VDEE", "d");
+	switch (video_supported) {
+	case TPACPI_VIDEO_570:
+		res = acpi_evalf(NULL, NULL,
+				 "\\_SB.PHS2", "vdd",
+				 TP_ACPI_VIDEO_570_PHS2CMD,
+				 status | TP_ACPI_VIDEO_570_PHS2SET);
+		break;
+	case TPACPI_VIDEO_770:
+		autosw = video_autosw_get();
+		if (autosw < 0)
+			return autosw;
 
-	return autosw & 1;
+		res = video_autosw_set(1);
+		if (res)
+			return res;
+		res = acpi_evalf(vid_handle, NULL,
+				 "ASWT", "vdd", status * 0x100, 0);
+		if (!autosw && video_autosw_set(autosw)) {
+			printk(IBM_ERR "video auto-switch left enabled due to error\n");
+			return -EIO;
+		}
+		break;
+	case TPACPI_VIDEO_NEW:
+		res = acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0x80) &&
+			acpi_evalf(NULL, NULL, "\\VSDS", "vdd", status, 1);
+		break;
+	default:
+		return -ENOSYS;
+	}
+
+	return (res)? 0 : -EIO;
 }
 
-static int video_switch(void)
+static int video_autosw_get(void)
 {
-	int autosw = video_autosw();
-	int ret;
+	int autosw = 0;
 
-	if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1))
-		return -EIO;
-	ret = video_supported == TPACPI_VIDEO_570 ?
-	    acpi_evalf(ec_handle, NULL, "_Q16", "v") :
-	    acpi_evalf(vid_handle, NULL, "VSWT", "v");
-	acpi_evalf(vid_handle, NULL, "_DOS", "vd", autosw);
+	switch (video_supported) {
+	case TPACPI_VIDEO_570:
+		if (!acpi_evalf(vid_handle, &autosw, "SWIT", "d"))
+			return -EIO;
+		break;
+	case TPACPI_VIDEO_770:
+	case TPACPI_VIDEO_NEW:
+		if (!acpi_evalf(vid_handle, &autosw, "^VDEE", "d"))
+			return -EIO;
+		break;
+	default:
+		return -ENOSYS;
+	}
 
-	return ret;
+	return autosw & 1;
 }
 
-static int video_expand(void)
+static int video_autosw_set(int enable)
 {
-	if (video_supported == TPACPI_VIDEO_570)
-		return acpi_evalf(ec_handle, NULL, "_Q17", "v");
-	else if (video_supported == TPACPI_VIDEO_770)
-		return acpi_evalf(vid_handle, NULL, "VEXP", "v");
-	else
-		return acpi_evalf(NULL, NULL, "\\VEXP", "v");
+	if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", (enable)? 1 : 0))
+		return -EIO;
+	return 0;
 }
 
-static int video_switch2(int status)
+static int video_outputsw_cycle(void)
 {
-	int ret;
-
-	if (video_supported == TPACPI_VIDEO_570) {
-		ret = acpi_evalf(NULL, NULL,
-				 "\\_SB.PHS2", "vdd", 0x8b, status | 0x80);
-	} else if (video_supported == TPACPI_VIDEO_770) {
-		int autosw = video_autosw();
-		if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1))
-			return -EIO;
+	int autosw = video_autosw_get();
+	int res;
 
-		ret = acpi_evalf(vid_handle, NULL,
-				 "ASWT", "vdd", status * 0x100, 0);
+	if (autosw < 0)
+		return autosw;
 
-		acpi_evalf(vid_handle, NULL, "_DOS", "vd", autosw);
-	} else {
-		ret = acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0x80) &&
-		    acpi_evalf(NULL, NULL, "\\VSDS", "vdd", status, 1);
+	switch (video_supported) {
+	case TPACPI_VIDEO_570:
+		res = video_autosw_set(1);
+		if (res)
+			return res;
+		res = acpi_evalf(ec_handle, NULL, "_Q16", "v");
+		break;
+	case TPACPI_VIDEO_770:
+	case TPACPI_VIDEO_NEW:
+		res = video_autosw_set(1);
+		if (res)
+			return res;
+		res = acpi_evalf(vid_handle, NULL, "VSWT", "v");
+		break;
+	default:
+		return -ENOSYS;
+	}
+	if (!autosw && video_autosw_set(autosw)) {
+		printk(IBM_ERR "video auto-switch left enabled due to error\n");
+		return -EIO;
 	}
 
-	return ret;
+	return (res)? 0 : -EIO;
+}
+
+static int video_expand_toggle(void)
+{
+	switch (video_supported) {
+	case TPACPI_VIDEO_570:
+		return acpi_evalf(ec_handle, NULL, "_Q17", "v")?
+			0 : -EIO;
+	case TPACPI_VIDEO_770:
+		return acpi_evalf(vid_handle, NULL, "VEXP", "v")?
+			0 : -EIO;
+	case TPACPI_VIDEO_NEW:
+		return acpi_evalf(NULL, NULL, "\\VEXP", "v")?
+			0 : -EIO;
+	default:
+		return -ENOSYS;
+	}
+	/* not reached */
 }
 
 static int video_read(char *p)
 {
-	int status = video_status();
-	int autosw = video_autosw();
+	int status, autosw;
 	int len = 0;
 
-	if (!video_supported) {
+	if (video_supported == TPACPI_VIDEO_NONE) {
 		len += sprintf(p + len, "status:\t\tnot supported\n");
 		return len;
 	}
 
+	status = video_outputsw_get();
+	if (status < 0)
+		return status;
+
+	autosw = video_autosw_get();
+	if (autosw < 0)
+		return autosw;
+
 	len += sprintf(p + len, "status:\t\tsupported\n");
 	len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0));
 	len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1));
@@ -1060,47 +1143,56 @@ static int video_write(char *buf)
 {
 	char *cmd;
 	int enable, disable, status;
+	int res;
 
-	if (!video_supported)
+	if (video_supported == TPACPI_VIDEO_NONE)
 		return -ENODEV;
 
-	enable = disable = 0;
+	enable = 0;
+	disable = 0;
 
 	while ((cmd = next_cmd(&buf))) {
 		if (strlencmp(cmd, "lcd_enable") == 0) {
-			enable |= 0x01;
+			enable |= TP_ACPI_VIDEO_S_LCD;
 		} else if (strlencmp(cmd, "lcd_disable") == 0) {
-			disable |= 0x01;
+			disable |= TP_ACPI_VIDEO_S_LCD;
 		} else if (strlencmp(cmd, "crt_enable") == 0) {
-			enable |= 0x02;
+			enable |= TP_ACPI_VIDEO_S_CRT;
 		} else if (strlencmp(cmd, "crt_disable") == 0) {
-			disable |= 0x02;
+			disable |= TP_ACPI_VIDEO_S_CRT;
 		} else if (video_supported == TPACPI_VIDEO_NEW &&
 			   strlencmp(cmd, "dvi_enable") == 0) {
-			enable |= 0x08;
+			enable |= TP_ACPI_VIDEO_S_DVI;
 		} else if (video_supported == TPACPI_VIDEO_NEW &&
 			   strlencmp(cmd, "dvi_disable") == 0) {
-			disable |= 0x08;
+			disable |= TP_ACPI_VIDEO_S_DVI;
 		} else if (strlencmp(cmd, "auto_enable") == 0) {
-			if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1))
-				return -EIO;
+			res = video_autosw_set(1);
+			if (res)
+				return res;
 		} else if (strlencmp(cmd, "auto_disable") == 0) {
-			if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 0))
-				return -EIO;
+			res = video_autosw_set(0);
+			if (res)
+				return res;
 		} else if (strlencmp(cmd, "video_switch") == 0) {
-			if (!video_switch())
-				return -EIO;
+			res = video_outputsw_cycle();
+			if (res)
+				return res;
 		} else if (strlencmp(cmd, "expand_toggle") == 0) {
-			if (!video_expand())
-				return -EIO;
+			res = video_expand_toggle();
+			if (res)
+				return res;
 		} else
 			return -EINVAL;
 	}
 
 	if (enable || disable) {
-		status = (video_status() & 0x0f & ~disable) | enable;
-		if (!video_switch2(status))
-			return -EIO;
+		status = video_outputsw_get();
+		if (status < 0)
+			return status;
+		res = video_outputsw_set((status & ~disable) | enable);
+		if (res)
+			return res;
 	}
 
 	return 0;
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index e06bad5..3a8718a 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -446,17 +446,32 @@ enum video_access_mode {
 	TPACPI_VIDEO_NEW,	/* all others */
 };
 
+enum {	/* video status flags, based on VIDEO_570 */
+	TP_ACPI_VIDEO_S_LCD = 0x01,	/* LCD output enabled */
+	TP_ACPI_VIDEO_S_CRT = 0x02,	/* CRT output enabled */
+	TP_ACPI_VIDEO_S_DVI = 0x08,	/* DVI output enabled */
+};
+
+enum {  /* TPACPI_VIDEO_570 constants */
+	TP_ACPI_VIDEO_570_PHSCMD = 0x87,	/* unknown magic constant :( */
+	TP_ACPI_VIDEO_570_PHSMASK = 0x03,	/* PHS bits that map to
+						 * video_status_flags */
+	TP_ACPI_VIDEO_570_PHS2CMD = 0x8b,	/* unknown magic constant :( */
+	TP_ACPI_VIDEO_570_PHS2SET = 0x80,	/* unknown magic constant :( */
+};
+
 static enum video_access_mode video_supported;
 static int video_orig_autosw;
 static acpi_handle vid_handle, vid2_handle;
 
 static int video_init(struct ibm_init_struct *iibm);
 static void video_exit(void);
-static int video_status(void);
-static int video_autosw(void);
-static int video_switch(void);
-static int video_switch2(int status);
-static int video_expand(void);
+static int video_outputsw_get(void);
+static int video_outputsw_set(int status);
+static int video_autosw_get(void);
+static int video_autosw_set(int enable);
+static int video_outputsw_cycle(void);
+static int video_expand_toggle(void);
 static int video_read(char *p);
 static int video_write(char *buf);
 
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 063/105] ACPI: thinkpad-acpi: clean up CMOS commands subdriver
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Some ThinkPad CMOS commands subdriver cleanups, and also rename/promote
cmos_eval to a ACPI helper function, as it is used by many other
subdrivers.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |   39 ++++++++++++++++++++-------------------
 drivers/misc/thinkpad_acpi.h |    4 +++-
 2 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 19c14bb..8829d3c 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -273,6 +273,17 @@ static int _sta(acpi_handle handle)
 	return status;
 }
 
+static int issue_thinkpad_cmos_command(int cmos_cmd)
+{
+	if (!cmos_handle)
+		return -ENXIO;
+
+	if (!acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd))
+		return -EIO;
+
+	return 0;
+}
+
 /*************************************************************************
  * ACPI device model
  */
@@ -1550,14 +1561,6 @@ static int __init cmos_init(struct ibm_init_struct *iibm)
 	return (cmos_handle)? 0 : 1;
 }
 
-static int cmos_eval(int cmos_cmd)
-{
-	if (cmos_handle)
-		return acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd);
-	else
-		return 1;
-}
-
 static int cmos_read(char *p)
 {
 	int len = 0;
@@ -1577,10 +1580,7 @@ static int cmos_read(char *p)
 static int cmos_write(char *buf)
 {
 	char *cmd;
-	int cmos_cmd;
-
-	if (!cmos_handle)
-		return -EINVAL;
+	int cmos_cmd, res;
 
 	while ((cmd = next_cmd(&buf))) {
 		if (sscanf(cmd, "%u", &cmos_cmd) == 1 &&
@@ -1589,8 +1589,9 @@ static int cmos_write(char *buf)
 		} else
 			return -EINVAL;
 
-		if (!cmos_eval(cmos_cmd))
-			return -EIO;
+		res = issue_thinkpad_cmos_command(cmos_cmd);
+		if (res)
+			return res;
 	}
 
 	return 0;
@@ -2093,7 +2094,7 @@ static int brightness_set(int value)
 	cmos_cmd = value > current_value ? TP_CMOS_BRIGHTNESS_UP : TP_CMOS_BRIGHTNESS_DOWN;
 	inc = value > current_value ? 1 : -1;
 	for (i = current_value; i != value; i += inc) {
-		if (!cmos_eval(cmos_cmd))
+		if (issue_thinkpad_cmos_command(cmos_cmd))
 			return -EIO;
 		if (!acpi_ec_write(brightness_offset, i + inc))
 			return -EIO;
@@ -2210,16 +2211,16 @@ static int volume_write(char *buf)
 			cmos_cmd = new_level > level ? TP_CMOS_VOLUME_UP : TP_CMOS_VOLUME_DOWN;
 			inc = new_level > level ? 1 : -1;
 
-			if (mute && (!cmos_eval(cmos_cmd) ||
+			if (mute && (issue_thinkpad_cmos_command(cmos_cmd) ||
 				     !acpi_ec_write(volume_offset, level)))
 				return -EIO;
 
 			for (i = level; i != new_level; i += inc)
-				if (!cmos_eval(cmos_cmd) ||
+				if (issue_thinkpad_cmos_command(cmos_cmd) ||
 				    !acpi_ec_write(volume_offset, i + inc))
 					return -EIO;
 
-			if (mute && (!cmos_eval(TP_CMOS_VOLUME_MUTE) ||
+			if (mute && (issue_thinkpad_cmos_command(TP_CMOS_VOLUME_MUTE) ||
 				     !acpi_ec_write(volume_offset,
 						    new_level + mute)))
 				return -EIO;
@@ -2228,7 +2229,7 @@ static int volume_write(char *buf)
 		if (new_mute != mute) {	/* level doesn't change */
 			cmos_cmd = new_mute ? TP_CMOS_VOLUME_MUTE : TP_CMOS_VOLUME_UP;
 
-			if (!cmos_eval(cmos_cmd) ||
+			if (issue_thinkpad_cmos_command(cmos_cmd) ||
 			    !acpi_ec_write(volume_offset, level + new_mute))
 				return -EIO;
 		}
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 3a8718a..fb0abb0 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -116,6 +116,9 @@ static void drv_acpi_handle_init(char *name,
 	drv_acpi_handle_init(#object, &object##_handle, *object##_parent,	\
 		object##_paths, ARRAY_SIZE(object##_paths), &object##_path)
 
+/* ThinkPad ACPI helpers */
+static int issue_thinkpad_cmos_command(int cmos_cmd);
+
 /* procfs support */
 static struct proc_dir_entry *proc_dir;
 
@@ -275,7 +278,6 @@ static int brightness_write(char *buf);
  * CMOS subdriver
  */
 
-static int cmos_eval(int cmos_cmd);
 static int cmos_read(char *p);
 static int cmos_write(char *buf);
 
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 064/105] ACPI: thinkpad-acpi: cleanup thermal subdriver for sysfs conversion
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Clean-up the thermal subdriver for sysfs conversion.  Make thermal_get_*
reentrancy-safe while at it, and add the missing thermal_read_mode variable
to the header file.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |   79 ++++++++++++++++++++++++++++--------------
 drivers/misc/thinkpad_acpi.h |    8 ++++
 2 files changed, 61 insertions(+), 26 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 8829d3c..e9aec87 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -1818,13 +1818,13 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
 
 		ta1 = ta2 = 0;
 		for (i = 0; i < 8; i++) {
-			if (likely(acpi_ec_read(0x78 + i, &t))) {
+			if (acpi_ec_read(TP_EC_THERMAL_TMP0 + i, &t)) {
 				ta1 |= t;
 			} else {
 				ta1 = 0;
 				break;
 			}
-			if (likely(acpi_ec_read(0xC0 + i, &t))) {
+			if (acpi_ec_read(TP_EC_THERMAL_TMP8 + i, &t)) {
 				ta2 |= t;
 			} else {
 				ta1 = 0;
@@ -1869,57 +1869,84 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
 	return (thermal_read_mode != TPACPI_THERMAL_NONE)? 0 : 1;
 }
 
-static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s)
+/* idx is zero-based */
+static int thermal_get_sensor(int idx, s32 *value)
 {
-	int i, t;
+	int t;
 	s8 tmp;
-	char tmpi[] = "TMPi";
+	char tmpi[5];
 
-	if (!s)
-		return -EINVAL;
+	t = TP_EC_THERMAL_TMP0;
 
 	switch (thermal_read_mode) {
 #if TPACPI_MAX_THERMAL_SENSORS >= 16
 	case TPACPI_THERMAL_TPEC_16:
-		for (i = 0; i < 8; i++) {
-			if (!acpi_ec_read(0xC0 + i, &tmp))
-				return -EIO;
-			s->temp[i + 8] = tmp * 1000;
+		if (idx >= 8 && idx <= 15) {
+			t = TP_EC_THERMAL_TMP8;
+			idx -= 8;
 		}
 		/* fallthrough */
 #endif
 	case TPACPI_THERMAL_TPEC_8:
-		for (i = 0; i < 8; i++) {
-			if (!acpi_ec_read(0x78 + i, &tmp))
+		if (idx <= 7) {
+			if (!acpi_ec_read(t + idx, &tmp))
 				return -EIO;
-			s->temp[i] = tmp * 1000;
+			*value = tmp * 1000;
+			return 0;
 		}
-		return (thermal_read_mode == TPACPI_THERMAL_TPEC_16) ? 16 : 8;
+		break;
 
 	case TPACPI_THERMAL_ACPI_UPDT:
-		if (!acpi_evalf(ec_handle, NULL, "UPDT", "v"))
-			return -EIO;
-		for (i = 0; i < 8; i++) {
-			tmpi[3] = '0' + i;
+		if (idx <= 7) {
+			snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx);
+			if (!acpi_evalf(ec_handle, NULL, "UPDT", "v"))
+				return -EIO;
 			if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
 				return -EIO;
-			s->temp[i] = (t - 2732) * 100;
+			*value = (t - 2732) * 100;
+			return 0;
 		}
-		return 8;
+		break;
 
 	case TPACPI_THERMAL_ACPI_TMP07:
-		for (i = 0; i < 8; i++) {
-			tmpi[3] = '0' + i;
+		if (idx <= 7) {
+			snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx);
 			if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
 				return -EIO;
-			s->temp[i] = t * 1000;
+			*value = t * 1000;
+			return 0;
 		}
-		return 8;
+		break;
 
 	case TPACPI_THERMAL_NONE:
 	default:
-		return 0;
+		return -ENOSYS;
 	}
+
+	return -EINVAL;
+}
+
+static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s)
+{
+	int res, i;
+	int n;
+
+	n = 8;
+	i = 0;
+
+	if (!s)
+		return -EINVAL;
+
+	if (thermal_read_mode == TPACPI_THERMAL_TPEC_16)
+		n = 16;
+
+	for(i = 0 ; i < n; i++) {
+		res = thermal_get_sensor(i, &s->temp[i]);
+		if (res)
+			return res;
+	}
+
+	return n;
 }
 
 static int thermal_read(char *p)
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index fb0abb0..6432b28 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -427,12 +427,20 @@ enum thermal_access_mode {
 	TPACPI_THERMAL_TPEC_16,		/* Use ACPI EC regs, 16 sensors */
 };
 
+enum { /* TPACPI_THERMAL_TPEC_* */
+	TP_EC_THERMAL_TMP0 = 0x78,	/* ACPI EC regs TMP 0..7 */
+	TP_EC_THERMAL_TMP8 = 0xC0,	/* ACPI EC regs TMP 8..15 */
+};
+
 #define TPACPI_MAX_THERMAL_SENSORS 16	/* Max thermal sensors supported */
 struct ibm_thermal_sensors_struct {
 	s32 temp[TPACPI_MAX_THERMAL_SENSORS];
 };
 
+static enum thermal_access_mode thermal_read_mode;
+
 static int thermal_init(struct ibm_init_struct *iibm);
+static int thermal_get_sensor(int idx, s32 *value);
 static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s);
 static int thermal_read(char *p);
 
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 065/105] ACPI: thinkpad-acpi: improve fan watchdog messages
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Improve some of the fan watchdog error messages to be a little more
helpful.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |   10 +++++++---
 1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index e9aec87..9b4eea4 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -2524,7 +2524,7 @@ static int fan_get_status(u8 *status)
 
 static void fan_exit(void)
 {
-	vdbg_printk(TPACPI_DBG_EXIT, "cancelling any pending watchdogs\n");
+	vdbg_printk(TPACPI_DBG_EXIT, "cancelling any pending fan watchdog tasks\n");
 	cancel_delayed_work(&fan_watchdog_task);
 	flush_scheduled_work();
 }
@@ -2554,9 +2554,13 @@ static int fan_get_speed(unsigned int *speed)
 
 static void fan_watchdog_fire(struct work_struct *ignored)
 {
+	int rc;
+
 	printk(IBM_NOTICE "fan watchdog: enabling fan\n");
-	if (fan_set_enable()) {
-		printk(IBM_ERR "fan watchdog: error while enabling fan\n");
+	rc = fan_set_enable();
+	if (rc < 0) {
+		printk(IBM_ERR "fan watchdog: error %d while enabling fan, "
+			"will try again later...\n", -rc);
 		/* reschedule for later */
 		fan_watchdog_reset();
 	}
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 066/105] ACPI: Disable MSI on request of FADT
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Shaohua Li, Len Brown

From: Shaohua Li <shaohua.li@intel.com>

The ACPI spec defines the bit and Microsoft uses it,
so Linux must use it too.

Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/pci/pci-acpi.c |    4 ++++
 include/acpi/actbl.h   |    1 +
 2 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index a064f36..b5ac810 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -317,6 +317,10 @@ static int __init acpi_pci_init(void)
 {
 	int ret;
 
+	if (acpi_gbl_FADT.boot_flags & BAF_MSI_NOT_SUPPORTED) {
+		printk(KERN_INFO"ACPI FADT declares the system doesn't support MSI, so disable it\n");
+		pci_no_msi();
+	}
 	ret = register_acpi_bus_type(&acpi_pci_bus);
 	if (ret)
 		return 0;
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h
index 09469e7..955adfb 100644
--- a/include/acpi/actbl.h
+++ b/include/acpi/actbl.h
@@ -276,6 +276,7 @@ enum acpi_prefered_pm_profiles {
 
 #define BAF_LEGACY_DEVICES              0x0001
 #define BAF_8042_KEYBOARD_CONTROLLER    0x0002
+#define BAF_MSI_NOT_SUPPORTED           0x0008
 
 #define FADT2_REVISION_ID               3
 #define FADT2_MINUS_REVISION_ID         2
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 067/105] ACPI: Improve acpi debug documentation
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Zhang Rui, Len Brown

From: Zhang Rui <rui.zhang@intel.com>

Now we use acpi.debug_level and acpi.debug_layer as kernel boot
parameters instead of acpi_dbg_level and acpi_dbg_layer.
Thanks to Andi Kleen for pointing it out.

Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 Documentation/kernel-parameters.txt |   32 +++++++++++++++++++++++++++-----
 1 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 12533a9..e3394eb 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -181,19 +181,41 @@ and is between 256 and 4096 characters. It is defined in the file
 			that require a timer override, but don't have
 			HPET
 
-	acpi_dbg_layer=	[HW,ACPI]
+	acpi.debug_layer=	[HW,ACPI]
 			Format: <int>
 			Each bit of the <int> indicates an ACPI debug layer,
 			1: enable, 0: disable. It is useful for boot time
 			debugging. After system has booted up, it can be set
-			via /proc/acpi/debug_layer.
-
-	acpi_dbg_level=	[HW,ACPI]
+			via /sys/module/acpi/parameters/debug_layer.
+			CONFIG_ACPI_DEBUG must be enabled for this to produce any output.
+			Available bits (add the numbers together) to enable debug output
+			for specific parts of the ACPI subsystem:
+			0x01 utilities 0x02 hardware 0x04 events 0x08 tables
+			0x10 namespace 0x20 parser 0x40 dispatcher
+			0x80 executer 0x100 resources 0x200 acpica debugger
+			0x400 os services 0x800 acpica disassembler.
+			The number can be in decimal or prefixed with 0x in hex.
+			Warning: Many of these options can produce a lot of
+			output and make your system unusable. Be very careful.
+
+	acpi.debug_level=	[HW,ACPI]
 			Format: <int>
 			Each bit of the <int> indicates an ACPI debug level,
 			1: enable, 0: disable. It is useful for boot time
 			debugging. After system has booted up, it can be set
-			via /proc/acpi/debug_level.
+			via /sys/module/acpi/parameters/debug_level.
+			CONFIG_ACPI_DEBUG must be enabled for this to produce any output.
+			Available bits (add the numbers together) to enable different
+			debug output levels of the ACPI subsystem:
+			0x01 error 0x02 warn 0x04 init 0x08 debug object
+			0x10 info 0x20 init names 0x40 parse 0x80 load
+			0x100 dispatch 0x200 execute 0x400 names 0x800 operation region
+			0x1000 bfield 0x2000 tables 0x4000 values 0x8000 objects
+			0x10000 resources 0x20000 user requests 0x40000 package.
+			The number can be in decimal or prefixed with 0x in hex.
+			Warning: Many of these options can produce a lot of
+			output and make your system unusable. Be very careful.
+
 
 	acpi_fake_ecdt	[HW,ACPI] Workaround failure due to BIOS lacking ECDT
 
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 068/105] ACPI: thinkpad-acpi: register with the device model
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Register thinkpad-acpi platform driver and platform device for the device
model.  Also register the platform device with the hwmon class.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 Documentation/thinkpad-acpi.txt |   40 ++++++++++++++++++++++++----
 drivers/misc/Kconfig            |    1 +
 drivers/misc/thinkpad_acpi.c    |   54 +++++++++++++++++++++++++++++++++++++++
 drivers/misc/thinkpad_acpi.h    |    8 ++++++
 4 files changed, 97 insertions(+), 6 deletions(-)

diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt
index 1a42b77..0e4e053 100644
--- a/Documentation/thinkpad-acpi.txt
+++ b/Documentation/thinkpad-acpi.txt
@@ -1,7 +1,7 @@
 		     ThinkPad ACPI Extras Driver
 
                             Version 0.14
-                          March 26th, 2007
+                          April 21st, 2007
 
                Borislav Deianov <borislav@users.sf.net>
 	     Henrique de Moraes Holschuh <hmh@hmh.eng.br>
@@ -67,11 +67,39 @@ thinkpad-specific bay functionality.
 Features
 --------
 
-The driver creates the /proc/acpi/ibm directory. There is a file under
-that directory for each feature described below. Note that while the
-driver is still in the alpha stage, the exact proc file format and
-commands supported by the various features is guaranteed to change
-frequently.
+The driver exports two different interfaces to userspace, which can be
+used to access the features it provides.  One is a legacy procfs-based
+interface, which will be removed at some time in the distant future.
+The other is a new sysfs-based interface which is not complete yet.
+
+The procfs interface creates the /proc/acpi/ibm directory.  There is a
+file under that directory for each feature it supports.  The procfs
+interface is mostly frozen, and will change very little if at all: it
+will not be extended to add any new functionality in the driver, instead
+all new functionality will be implemented on the sysfs interface.
+
+The sysfs interface tries to blend in the generic Linux sysfs subsystems
+and classes as much as possible.  Since some of these subsystems are not
+yet ready or stabilized, it is expected that this interface will change,
+and any and all userspace programs must deal with it.
+
+
+Notes about the sysfs interface:
+
+Unlike what was done with the procfs interface, correctness when talking
+to the sysfs interfaces will be enforced, as will correctness in the
+thinkpad-acpi's implementation of sysfs interfaces.
+
+Also, any bugs in the thinkpad-acpi sysfs driver code or in the
+thinkpad-acpi's implementation of the sysfs interfaces will be fixed for
+maximum correctness, even if that means changing an interface in
+non-compatible ways.  As these interfaces mature both in the kernel and
+in thinkpad-acpi, such changes should become quite rare.
+
+Applications interfacing to the thinkpad-acpi sysfs interfaces must
+follow all sysfs guidelines and correctly process all errors (the sysfs
+interface makes extensive use of errors).  File descriptors and open /
+close operations to the sysfs inodes must also be properly implemented.
 
 Driver version -- /proc/acpi/ibm/driver
 ---------------------------------------
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 44e4c8f..445c4b1 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -126,6 +126,7 @@ config THINKPAD_ACPI
 	tristate "ThinkPad ACPI Laptop Extras"
 	depends on X86 && ACPI
 	select BACKLIGHT_CLASS_DEVICE
+	select HWMON
 	---help---
 	  This is a driver for the IBM and Lenovo ThinkPad laptops. It adds
 	  support for Fn-Fx key combinations, Bluetooth control, video
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 9b4eea4..e47eaf7 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -477,6 +477,25 @@ static char *next_cmd(char **cmds)
 /****************************************************************************
  ****************************************************************************
  *
+ * Device model: hwmon and platform
+ *
+ ****************************************************************************
+ ****************************************************************************/
+
+static struct platform_device *tpacpi_pdev = NULL;
+static struct class_device *tpacpi_hwmon = NULL;
+
+static struct platform_driver tpacpi_pdriver = {
+	.driver = {
+		.name = IBM_DRVR_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+
+/****************************************************************************
+ ****************************************************************************
+ *
  * Subdrivers
  *
  ****************************************************************************
@@ -3225,10 +3244,12 @@ static int __init thinkpad_acpi_module_init(void)
 {
 	int ret, i;
 
+	/* Driver-level probe */
 	ret = probe_for_thinkpad();
 	if (ret)
 		return ret;
 
+	/* Driver initialization */
 	ibm_thinkpad_ec_found = check_dmi_for_ec();
 	IBM_ACPIHANDLE_INIT(ecrd);
 	IBM_ACPIHANDLE_INIT(ecwr);
@@ -3241,6 +3262,31 @@ static int __init thinkpad_acpi_module_init(void)
 	}
 	proc_dir->owner = THIS_MODULE;
 
+	ret = platform_driver_register(&tpacpi_pdriver);
+	if (ret) {
+		printk(IBM_ERR "unable to register platform driver\n");
+		thinkpad_acpi_module_exit();
+		return ret;
+	}
+
+	/* Device initialization */
+	tpacpi_pdev = platform_device_register_simple(IBM_DRVR_NAME, -1,
+							NULL, 0);
+	if (IS_ERR(tpacpi_pdev)) {
+		ret = PTR_ERR(tpacpi_pdev);
+		tpacpi_pdev = NULL;
+		printk(IBM_ERR "unable to register platform device\n");
+		thinkpad_acpi_module_exit();
+		return ret;
+	}
+	tpacpi_hwmon = hwmon_device_register(&tpacpi_pdev->dev);
+	if (IS_ERR(tpacpi_hwmon)) {
+		ret = PTR_ERR(tpacpi_hwmon);
+		tpacpi_hwmon = NULL;
+		printk(IBM_ERR "unable to register hwmon device\n");
+		thinkpad_acpi_module_exit();
+		return ret;
+	}
 	for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
 		ret = ibm_init(&ibms_init[i]);
 		if (ret >= 0 && *ibms_init[i].param)
@@ -3266,6 +3312,14 @@ static void thinkpad_acpi_module_exit(void)
 
 	dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n");
 
+	if (tpacpi_hwmon)
+		hwmon_device_unregister(tpacpi_hwmon);
+
+	if (tpacpi_pdev)
+		platform_device_unregister(tpacpi_pdev);
+
+	platform_driver_unregister(&tpacpi_pdriver);
+
 	if (proc_dir)
 		remove_proc_entry(IBM_PROC_DIR, acpi_root_dir);
 
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 6432b28..fea5809 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -34,6 +34,8 @@
 #include <linux/proc_fs.h>
 #include <linux/backlight.h>
 #include <linux/fb.h>
+#include <linux/platform_device.h>
+#include <linux/hwmon.h>
 #include <asm/uaccess.h>
 
 #include <linux/dmi.h>
@@ -56,6 +58,7 @@
 
 #define IBM_PROC_DIR "ibm"
 #define IBM_ACPI_EVENT_PREFIX "ibm"
+#define IBM_DRVR_NAME IBM_FILE
 
 #define IBM_LOG IBM_FILE ": "
 #define IBM_ERR	   KERN_ERR    IBM_LOG
@@ -130,6 +133,11 @@ static int dispatch_procfs_write(struct file *file,
 		unsigned long count, void *data);
 static char *next_cmd(char **cmds);
 
+/* Device model */
+static struct platform_device *tpacpi_pdev;
+static struct class_device *tpacpi_hwmon;
+static struct platform_driver tpacpi_pdriver;
+
 /* Module */
 static int experimental;
 static u32 dbg_level;
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 069/105] ACPI: thinkpad-acpi: driver sysfs conversion
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Add the sysfs attributes for the platform driver.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 Documentation/thinkpad-acpi.txt |   42 +++++++++++++++++-
 drivers/misc/thinkpad_acpi.c    |   90 +++++++++++++++++++++++++++++++++++++++
 drivers/misc/thinkpad_acpi.h    |    3 +
 3 files changed, 133 insertions(+), 2 deletions(-)

diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt
index 0e4e053..cc079af 100644
--- a/Documentation/thinkpad-acpi.txt
+++ b/Documentation/thinkpad-acpi.txt
@@ -101,11 +101,39 @@ follow all sysfs guidelines and correctly process all errors (the sysfs
 interface makes extensive use of errors).  File descriptors and open /
 close operations to the sysfs inodes must also be properly implemented.
 
-Driver version -- /proc/acpi/ibm/driver
----------------------------------------
+The version of thinkpad-acpi's sysfs interface is exported by the driver
+as a driver attribute (see below).
+
+Sysfs driver attributes are on the driver's sysfs attribute space,
+for 2.6.20 this is /sys/bus/platform/drivers/thinkpad-acpi/.
+
+Sysfs device attributes are on the driver's sysfs attribute space,
+for 2.6.20 this is /sys/devices/platform/thinkpad-acpi/.
+
+Driver version
+--------------
+
+procfs: /proc/acpi/ibm/driver
+sysfs driver attribute: version
 
 The driver name and version. No commands can be written to this file.
 
+Sysfs interface version
+-----------------------
+
+sysfs driver attribute: interface_version
+
+Version of the thinkpad-acpi sysfs interface, as an unsigned long
+(output in hex format: 0xAAAABBCC), where:
+	AAAA - major revision
+	BB - minor revision
+	CC - bugfix revision
+
+The sysfs interface version changelog for the driver can be found at the
+end of this document.  Changes to the sysfs interface done by the kernel
+subsystems are not documented here, nor are they tracked by this
+attribute.
+
 Hot keys -- /proc/acpi/ibm/hotkey
 ---------------------------------
 
@@ -745,9 +773,19 @@ to enable more than one output class, just add their values.
 There is also a kernel build option to enable more debugging
 information, which may be necessary to debug driver problems.
 
+The level of debugging information output by the driver can be changed
+at runtime through sysfs, using the driver attribute debug_level.  The
+attribute takes the same bitmask as the debug module parameter above.
+
 Force loading of module
 -----------------------
 
 If thinkpad-acpi refuses to detect your ThinkPad, you can try to specify
 the module parameter force_load=1.  Regardless of whether this works or
 not, please contact ibm-acpi-devel@lists.sourceforge.net with a report.
+
+
+Sysfs interface changelog:
+
+0x000100:	Initial sysfs support, as a single platform driver and
+		device.
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index e47eaf7..a31d00d 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -22,6 +22,7 @@
  */
 
 #define IBM_VERSION "0.14"
+#define TPACPI_SYSFS_VERSION 0x000100
 
 /*
  *  Changelog:
@@ -493,6 +494,87 @@ static struct platform_driver tpacpi_pdriver = {
 };
 
 
+/*************************************************************************
+ * thinkpad-acpi driver attributes
+ */
+
+/* interface_version --------------------------------------------------- */
+static ssize_t tpacpi_driver_interface_version_show(
+				struct device_driver *drv,
+				char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "0x%08x\n", TPACPI_SYSFS_VERSION);
+}
+
+static DRIVER_ATTR(interface_version, S_IRUGO,
+		tpacpi_driver_interface_version_show, NULL);
+
+/* debug_level --------------------------------------------------------- */
+static ssize_t tpacpi_driver_debug_show(struct device_driver *drv,
+						char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "0x%04x\n", dbg_level);
+}
+
+static ssize_t tpacpi_driver_debug_store(struct device_driver *drv,
+						const char *buf, size_t count)
+{
+	unsigned long t;
+	char *endp;
+
+	t = simple_strtoul(buf, &endp, 0);
+	while (*endp && isspace(*endp))
+		endp++;
+	if (*endp)
+		return -EINVAL;
+
+	dbg_level = t;
+
+	return count;
+}
+
+static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
+		tpacpi_driver_debug_show, tpacpi_driver_debug_store);
+
+/* version ------------------------------------------------------------- */
+static ssize_t tpacpi_driver_version_show(struct device_driver *drv,
+						char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s v%s\n", IBM_DESC, IBM_VERSION);
+}
+
+static DRIVER_ATTR(version, S_IRUGO,
+		tpacpi_driver_version_show, NULL);
+
+/* --------------------------------------------------------------------- */
+
+static struct driver_attribute* tpacpi_driver_attributes[] = {
+	&driver_attr_debug_level, &driver_attr_version,
+	&driver_attr_interface_version,
+};
+
+static int __init tpacpi_create_driver_attributes(struct device_driver *drv)
+{
+	int i, res;
+
+	i = 0;
+	res = 0;
+	while (!res && i < ARRAY_SIZE(tpacpi_driver_attributes)) {
+		res = driver_create_file(drv, tpacpi_driver_attributes[i]);
+		i++;
+	}
+
+	return res;
+}
+
+static void tpacpi_remove_driver_attributes(struct device_driver *drv)
+{
+	int i;
+
+	for(i = 0; i < ARRAY_SIZE(tpacpi_driver_attributes); i++)
+		driver_remove_file(drv, tpacpi_driver_attributes[i]);
+}
+
 /****************************************************************************
  ****************************************************************************
  *
@@ -3268,6 +3350,13 @@ static int __init thinkpad_acpi_module_init(void)
 		thinkpad_acpi_module_exit();
 		return ret;
 	}
+	ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver);
+	if (ret) {
+		printk(IBM_ERR "unable to create sysfs driver attributes\n");
+		thinkpad_acpi_module_exit();
+		return ret;
+	}
+
 
 	/* Device initialization */
 	tpacpi_pdev = platform_device_register_simple(IBM_DRVR_NAME, -1,
@@ -3318,6 +3407,7 @@ static void thinkpad_acpi_module_exit(void)
 	if (tpacpi_pdev)
 		platform_device_unregister(tpacpi_pdev);
 
+	tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver);
 	platform_driver_unregister(&tpacpi_pdriver);
 
 	if (proc_dir)
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index fea5809..3786058 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -32,6 +32,7 @@
 #include <linux/list.h>
 
 #include <linux/proc_fs.h>
+#include <linux/sysfs.h>
 #include <linux/backlight.h>
 #include <linux/fb.h>
 #include <linux/platform_device.h>
@@ -137,6 +138,8 @@ static char *next_cmd(char **cmds);
 static struct platform_device *tpacpi_pdev;
 static struct class_device *tpacpi_hwmon;
 static struct platform_driver tpacpi_pdriver;
+static int tpacpi_create_driver_attributes(struct device_driver *drv);
+static void tpacpi_remove_driver_attributes(struct device_driver *drv);
 
 /* Module */
 static int experimental;
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 070/105] ACPI: thinkpad-acpi: add infrastructure for the sysfs device attributes
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Add infrastructure to deal with sysfs attributes and grouping, and helpers
for common sysfs parsing.  Switch driver attributes to use them.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |   86 +++++++++++++++++++++++++++++++++++++++--
 drivers/misc/thinkpad_acpi.h |   21 ++++++++++
 2 files changed, 102 insertions(+), 5 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index a31d00d..ca6d15c 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -520,12 +520,8 @@ static ssize_t tpacpi_driver_debug_store(struct device_driver *drv,
 						const char *buf, size_t count)
 {
 	unsigned long t;
-	char *endp;
 
-	t = simple_strtoul(buf, &endp, 0);
-	while (*endp && isspace(*endp))
-		endp++;
-	if (*endp)
+	if (parse_strtoul(buf, 0xffff, &t))
 		return -EINVAL;
 
 	dbg_level = t;
@@ -575,6 +571,86 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv)
 		driver_remove_file(drv, tpacpi_driver_attributes[i]);
 }
 
+/*************************************************************************
+ * sysfs support helpers
+ */
+
+struct attribute_set_obj {
+	struct attribute_set s;
+	struct attribute *a;
+} __attribute__((packed));
+
+static struct attribute_set *create_attr_set(unsigned int max_members,
+						const char* name)
+{
+	struct attribute_set_obj *sobj;
+
+	if (max_members == 0)
+		return NULL;
+
+	/* Allocates space for implicit NULL at the end too */
+	sobj = kzalloc(sizeof(struct attribute_set_obj) +
+		    max_members * sizeof(struct attribute *),
+		    GFP_KERNEL);
+	if (!sobj)
+		return NULL;
+	sobj->s.max_members = max_members;
+	sobj->s.group.attrs = &sobj->a;
+	sobj->s.group.name = name;
+
+	return &sobj->s;
+}
+
+/* not multi-threaded safe, use it in a single thread per set */
+static int add_to_attr_set(struct attribute_set* s, struct attribute *attr)
+{
+	if (!s || !attr)
+		return -EINVAL;
+
+	if (s->members >= s->max_members)
+		return -ENOMEM;
+
+	s->group.attrs[s->members] = attr;
+	s->members++;
+
+	return 0;
+}
+
+static int add_many_to_attr_set(struct attribute_set* s,
+			struct attribute **attr,
+			unsigned int count)
+{
+	int i, res;
+
+	for (i = 0; i < count; i++) {
+		res = add_to_attr_set(s, attr[i]);
+		if (res)
+			return res;
+	}
+
+	return 0;
+}
+
+static void delete_attr_set(struct attribute_set* s, struct kobject *kobj)
+{
+	sysfs_remove_group(kobj, &s->group);
+	destroy_attr_set(s);
+}
+
+static int parse_strtoul(const char *buf,
+		unsigned long max, unsigned long *value)
+{
+	char *endp;
+
+	*value = simple_strtoul(buf, &endp, 0);
+	while (*endp && isspace(*endp))
+		endp++;
+	if (*endp || *value > max)
+		return -EINVAL;
+
+	return 0;
+}
+
 /****************************************************************************
  ****************************************************************************
  *
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 3786058..84fdefe 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -134,6 +134,27 @@ static int dispatch_procfs_write(struct file *file,
 		unsigned long count, void *data);
 static char *next_cmd(char **cmds);
 
+/* sysfs support */
+struct attribute_set {
+	unsigned int members, max_members;
+	struct attribute_group group;
+};
+
+static struct attribute_set *create_attr_set(unsigned int max_members,
+						const char* name);
+#define destroy_attr_set(_set) \
+	kfree(_set);
+static int add_to_attr_set(struct attribute_set* s, struct attribute *attr);
+static int add_many_to_attr_set(struct attribute_set* s,
+			struct attribute **attr,
+			unsigned int count);
+#define register_attr_set_with_sysfs(_attr_set, _kobj) \
+	sysfs_create_group(_kobj, &_attr_set->group)
+static void delete_attr_set(struct attribute_set* s, struct kobject *kobj);
+
+static int parse_strtoul(const char *buf, unsigned long max,
+			unsigned long *value);
+
 /* Device model */
 static struct platform_device *tpacpi_pdev;
 static struct class_device *tpacpi_hwmon;
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 071/105] ACPI: thinkpad-acpi: protect fan and hotkey data structures
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Add proper mutex locking to some data structures access subject to races
due to concurrent access of driver functions on the hotkey and fan
subdrivers.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |  114 ++++++++++++++++++++++++++++++++----------
 drivers/misc/thinkpad_acpi.h |    5 ++
 2 files changed, 92 insertions(+), 27 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index ca6d15c..aa69ff0 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -704,6 +704,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
 	vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n");
 
 	IBM_ACPIHANDLE_INIT(hkey);
+	mutex_init(&hotkey_mutex);
 
 	/* hotkey not supported on 570 */
 	tp_features.hotkey = hkey_handle != NULL;
@@ -752,6 +753,9 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
 	}
 }
 
+/*
+ * Call with hotkey_mutex held
+ */
 static int hotkey_get(int *status, int *mask)
 {
 	if (!acpi_evalf(hkey_handle, status, "DHKC", "d"))
@@ -764,6 +768,9 @@ static int hotkey_get(int *status, int *mask)
 	return 0;
 }
 
+/*
+ * Call with hotkey_mutex held
+ */
 static int hotkey_set(int status, int mask)
 {
 	int i;
@@ -792,7 +799,11 @@ static int hotkey_read(char *p)
 		return len;
 	}
 
+	res = mutex_lock_interruptible(&hotkey_mutex);
+	if (res < 0)
+		return res;
 	res = hotkey_get(&status, &mask);
+	mutex_unlock(&hotkey_mutex);
 	if (res)
 		return res;
 
@@ -818,10 +829,15 @@ static int hotkey_write(char *buf)
 	if (!tp_features.hotkey)
 		return -ENODEV;
 
+	res = mutex_lock_interruptible(&hotkey_mutex);
+	if (res < 0)
+		return res;
+
 	res = hotkey_get(&status, &mask);
 	if (res)
-		return res;
+		goto errexit;
 
+	res = 0;
 	while ((cmd = next_cmd(&buf))) {
 		if (strlencmp(cmd, "enable") == 0) {
 			status = 1;
@@ -834,18 +850,19 @@ static int hotkey_write(char *buf)
 			/* mask set */
 		} else if (sscanf(cmd, "%x", &mask) == 1) {
 			/* mask set */
-		} else
-			return -EINVAL;
+		} else {
+			res = -EINVAL;
+			goto errexit;
+		}
 		do_cmd = 1;
 	}
 
-	if (do_cmd) {
+	if (do_cmd)
 		res = hotkey_set(status, mask);
-		if (res)
-			return res;
-	}
 
-	return 0;
+errexit:
+	mutex_unlock(&hotkey_mutex);
+	return res;
 }
 
 static struct tp_acpi_drv_struct ibm_hotkey_acpidriver = {
@@ -2575,6 +2592,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)
 {
 	vdbg_printk(TPACPI_DBG_INIT, "initializing fan subdriver\n");
 
+	mutex_init(&fan_mutex);
 	fan_status_access_mode = TPACPI_FAN_NONE;
 	fan_control_access_mode = TPACPI_FAN_WR_NONE;
 	fan_control_commands = 0;
@@ -2764,10 +2782,17 @@ static void fan_watchdog_reset(void)
 
 static int fan_set_level(int level)
 {
+	int res;
+
 	switch (fan_control_access_mode) {
 	case TPACPI_FAN_WR_ACPI_SFAN:
 		if (level >= 0 && level <= 7) {
-			if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level))
+			res = mutex_lock_interruptible(&fan_mutex);
+			if (res < 0)
+				return res;
+			res = acpi_evalf(sfan_handle, NULL, NULL, "vd", level);
+			mutex_unlock(&fan_mutex);
+			if (!res)
 				return -EIO;
 		} else
 			return -EINVAL;
@@ -2780,7 +2805,12 @@ static int fan_set_level(int level)
 		    ((level < 0) || (level > 7)))
 			return -EINVAL;
 
-		if (!acpi_ec_write(fan_status_offset, level))
+		res = mutex_lock_interruptible(&fan_mutex);
+		if (res < 0)
+			return res;
+		res = acpi_ec_write(fan_status_offset, level);
+		mutex_unlock(&fan_mutex);
+		if (!res)
 			return -EIO;
 		else
 			tp_features.fan_ctrl_status_undef = 0;
@@ -2797,25 +2827,33 @@ static int fan_set_enable(void)
 	u8 s;
 	int rc;
 
+	rc = mutex_lock_interruptible(&fan_mutex);
+	if (rc < 0)
+		return rc;
+
 	switch (fan_control_access_mode) {
 	case TPACPI_FAN_WR_ACPI_FANS:
 	case TPACPI_FAN_WR_TPEC:
-		if ((rc = fan_get_status(&s)) < 0)
-			return rc;
+		rc = fan_get_status(&s);
+		if (rc < 0)
+			break;
 
 		/* Don't go out of emergency fan mode */
 		if (s != 7)
 			s = TP_EC_FAN_AUTO;
 
 		if (!acpi_ec_write(fan_status_offset, s))
-			return -EIO;
-		else
+			rc = -EIO;
+		else {
 			tp_features.fan_ctrl_status_undef = 0;
+			rc = 0;
+		}
 		break;
 
 	case TPACPI_FAN_WR_ACPI_SFAN:
-		if ((rc = fan_get_status(&s)) < 0)
-			return rc;
+		rc = fan_get_status(&s);
+		if (rc < 0)
+			break;
 
 		s &= 0x07;
 
@@ -2824,53 +2862,75 @@ static int fan_set_enable(void)
 			s = 4;
 
 		if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", s))
-			return -EIO;
+			rc= -EIO;
+		else
+			rc = 0;
 		break;
 
 	default:
-		return -ENXIO;
+		rc = -ENXIO;
 	}
-	return 0;
+
+	mutex_unlock(&fan_mutex);
+	return rc;
 }
 
 static int fan_set_disable(void)
 {
+	int rc;
+
+	rc = mutex_lock_interruptible(&fan_mutex);
+	if (rc < 0)
+		return rc;
+
+	rc = 0;
 	switch (fan_control_access_mode) {
 	case TPACPI_FAN_WR_ACPI_FANS:
 	case TPACPI_FAN_WR_TPEC:
 		if (!acpi_ec_write(fan_status_offset, 0x00))
-			return -EIO;
+			rc = -EIO;
 		else
 			tp_features.fan_ctrl_status_undef = 0;
 		break;
 
 	case TPACPI_FAN_WR_ACPI_SFAN:
 		if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", 0x00))
-			return -EIO;
+			rc = -EIO;
 		break;
 
 	default:
-		return -ENXIO;
+		rc = -ENXIO;
 	}
-	return 0;
+
+	mutex_unlock(&fan_mutex);
+	return rc;
 }
 
 static int fan_set_speed(int speed)
 {
+	int rc;
+
+	rc = mutex_lock_interruptible(&fan_mutex);
+	if (rc < 0)
+		return rc;
+
+	rc = 0;
 	switch (fan_control_access_mode) {
 	case TPACPI_FAN_WR_ACPI_FANS:
 		if (speed >= 0 && speed <= 65535) {
 			if (!acpi_evalf(fans_handle, NULL, NULL, "vddd",
 					speed, speed, speed))
-				return -EIO;
+				rc = -EIO;
 		} else
-			return -EINVAL;
+			rc = -EINVAL;
 		break;
 
 	default:
-		return -ENXIO;
+		rc = -ENXIO;
 	}
-	return 0;
+
+	mutex_unlock(&fan_mutex);
+	return rc;
 }
 
 static int fan_read(char *p)
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 84fdefe..a9feb53 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -30,6 +30,7 @@
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/list.h>
+#include <linux/mutex.h>
 
 #include <linux/proc_fs.h>
 #include <linux/sysfs.h>
@@ -375,6 +376,8 @@ static enum fan_control_commands fan_control_commands;
 static u8 fan_control_initial_status;
 static int fan_watchdog_maxinterval;
 
+struct mutex fan_mutex;
+
 static acpi_handle fans_handle, gfan_handle, sfan_handle;
 
 static int fan_init(struct ibm_init_struct *iibm);
@@ -403,6 +406,8 @@ static int fan_write_cmd_watchdog(const char *cmd, int *rc);
 static int hotkey_orig_status;
 static int hotkey_orig_mask;
 
+static struct mutex hotkey_mutex;
+
 static int hotkey_init(struct ibm_init_struct *iibm);
 static void hotkey_exit(void);
 static int hotkey_get(int *status, int *mask);
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 072/105] ACPI: thinkpad-acpi: add sysfs support to the thermal subdriver
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Export thinkpad thermal sensors to sysfs, following the hwmon
specification for thermal monitoring sensors.

ThinkPad thermal monitoring is done by the EC.  Sensors can show up or
disappear at runtime when they are inside hotswappable hardware, such as
batteries.  Sensors that are not available return -ENXIO when accessed.

Up to 16 thermal sensors are supported on new firmware (but nobody has
reported a ThinkPad with more than 12 sensors so far), and 8 sensors are
supported on older firmware.  Thermal sensor mapping is model-specific.
Precision varies, it is 1 degree Celcius on new ThinkPads, but higher on
some older models.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 Documentation/thinkpad-acpi.txt |   26 ++++++--
 drivers/misc/thinkpad_acpi.c    |  122 ++++++++++++++++++++++++++++++++++++++-
 drivers/misc/thinkpad_acpi.h    |    2 +
 3 files changed, 143 insertions(+), 7 deletions(-)

diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt
index cc079af..80c0bf2 100644
--- a/Documentation/thinkpad-acpi.txt
+++ b/Documentation/thinkpad-acpi.txt
@@ -458,17 +458,17 @@ X40:
 	16 - one medium-pitched beep repeating constantly, stop with 17
 	17 - stop 16
 
-Temperature sensors -- /proc/acpi/ibm/thermal
----------------------------------------------
+Temperature sensors
+-------------------
+
+procfs: /proc/acpi/ibm/thermal
+sysfs device attributes: (hwmon) temp*_input
 
 Most ThinkPads include six or more separate temperature sensors but
 only expose the CPU temperature through the standard ACPI methods.
 This feature shows readings from up to eight different sensors on older
 ThinkPads, and it has experimental support for up to sixteen different
-sensors on newer ThinkPads.  Readings from sensors that are not available
-return -128.
-
-No commands can be written to this file.
+sensors on newer ThinkPads.
 
 EXPERIMENTAL: The 16-sensors feature is marked EXPERIMENTAL because the
 implementation directly accesses hardware registers and may not work as
@@ -525,6 +525,20 @@ The A31 has a very atypical layout for the thermal sensors
 8:  Bay Battery: secondary sensor
 
 
+Procfs notes:
+	Readings from sensors that are not available return -128.
+	No commands can be written to this file.
+
+Sysfs notes:
+	Sensors that are not available return the ENXIO error.  This
+	status may change at runtime, as there are hotplug thermal
+	sensors, like those inside the batteries and docks.
+
+	thinkpad-acpi thermal sensors are reported through the hwmon
+	subsystem, and follow all of the hwmon guidelines at
+	Documentation/hwmon.
+
+
 EXPERIMENTAL: Embedded controller register dump -- /proc/acpi/ibm/ecdump
 ------------------------------------------------------------------------
 
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index aa69ff0..d5526e8 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -1992,11 +1992,91 @@ static struct ibm_struct beep_driver_data = {
 
 static enum thermal_access_mode thermal_read_mode;
 
+/* sysfs temp##_input -------------------------------------------------- */
+
+static ssize_t thermal_temp_input_show(struct device *dev,
+			   struct device_attribute *attr,
+			   char *buf)
+{
+	struct sensor_device_attribute *sensor_attr =
+					to_sensor_dev_attr(attr);
+	int idx = sensor_attr->index;
+	s32 value;
+	int res;
+
+	res = thermal_get_sensor(idx, &value);
+	if (res)
+		return res;
+	if (value == TP_EC_THERMAL_TMP_NA * 1000)
+		return -ENXIO;
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", value);
+}
+
+#define THERMAL_SENSOR_ATTR_TEMP(_idxA, _idxB) \
+	 SENSOR_ATTR(temp##_idxA##_input, S_IRUGO, thermal_temp_input_show, NULL, _idxB)
+
+static struct sensor_device_attribute sensor_dev_attr_thermal_temp_input[] = {
+	THERMAL_SENSOR_ATTR_TEMP(1, 0),
+	THERMAL_SENSOR_ATTR_TEMP(2, 1),
+	THERMAL_SENSOR_ATTR_TEMP(3, 2),
+	THERMAL_SENSOR_ATTR_TEMP(4, 3),
+	THERMAL_SENSOR_ATTR_TEMP(5, 4),
+	THERMAL_SENSOR_ATTR_TEMP(6, 5),
+	THERMAL_SENSOR_ATTR_TEMP(7, 6),
+	THERMAL_SENSOR_ATTR_TEMP(8, 7),
+	THERMAL_SENSOR_ATTR_TEMP(9, 8),
+	THERMAL_SENSOR_ATTR_TEMP(10, 9),
+	THERMAL_SENSOR_ATTR_TEMP(11, 10),
+	THERMAL_SENSOR_ATTR_TEMP(12, 11),
+	THERMAL_SENSOR_ATTR_TEMP(13, 12),
+	THERMAL_SENSOR_ATTR_TEMP(14, 13),
+	THERMAL_SENSOR_ATTR_TEMP(15, 14),
+	THERMAL_SENSOR_ATTR_TEMP(16, 15),
+};
+
+#define THERMAL_ATTRS(X) \
+	&sensor_dev_attr_thermal_temp_input[X].dev_attr.attr
+
+static struct attribute *thermal_temp_input_attr[] = {
+	THERMAL_ATTRS(8),
+	THERMAL_ATTRS(9),
+	THERMAL_ATTRS(10),
+	THERMAL_ATTRS(11),
+	THERMAL_ATTRS(12),
+	THERMAL_ATTRS(13),
+	THERMAL_ATTRS(14),
+	THERMAL_ATTRS(15),
+	THERMAL_ATTRS(0),
+	THERMAL_ATTRS(1),
+	THERMAL_ATTRS(2),
+	THERMAL_ATTRS(3),
+	THERMAL_ATTRS(4),
+	THERMAL_ATTRS(5),
+	THERMAL_ATTRS(6),
+	THERMAL_ATTRS(7),
+	NULL
+};
+
+static const struct attribute_group thermal_temp_input16_group = {
+	.attrs = thermal_temp_input_attr
+};
+
+static const struct attribute_group thermal_temp_input8_group = {
+	.attrs = &thermal_temp_input_attr[8]
+};
+
+#undef THERMAL_SENSOR_ATTR_TEMP
+#undef THERMAL_ATTRS
+
+/* --------------------------------------------------------------------- */
+
 static int __init thermal_init(struct ibm_init_struct *iibm)
 {
 	u8 t, ta1, ta2;
 	int i;
 	int acpi_tmp7;
+	int res;
 
 	vdbg_printk(TPACPI_DBG_INIT, "initializing thermal subdriver\n");
 
@@ -2060,7 +2140,46 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
 		str_supported(thermal_read_mode != TPACPI_THERMAL_NONE),
 		thermal_read_mode);
 
-	return (thermal_read_mode != TPACPI_THERMAL_NONE)? 0 : 1;
+	switch(thermal_read_mode) {
+	case TPACPI_THERMAL_TPEC_16:
+		res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
+				&thermal_temp_input16_group);
+		if (res)
+			return res;
+		break;
+	case TPACPI_THERMAL_TPEC_8:
+	case TPACPI_THERMAL_ACPI_TMP07:
+	case TPACPI_THERMAL_ACPI_UPDT:
+		res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
+				&thermal_temp_input8_group);
+		if (res)
+			return res;
+		break;
+	case TPACPI_THERMAL_NONE:
+	default:
+		return 1;
+	}
+
+	return 0;
+}
+
+static void thermal_exit(void)
+{
+	switch(thermal_read_mode) {
+	case TPACPI_THERMAL_TPEC_16:
+		sysfs_remove_group(&tpacpi_pdev->dev.kobj,
+				   &thermal_temp_input16_group);
+		break;
+	case TPACPI_THERMAL_TPEC_8:
+	case TPACPI_THERMAL_ACPI_TMP07:
+	case TPACPI_THERMAL_ACPI_UPDT:
+		sysfs_remove_group(&tpacpi_pdev->dev.kobj,
+				   &thermal_temp_input16_group);
+		break;
+	case TPACPI_THERMAL_NONE:
+	default:
+		break;
+	}
 }
 
 /* idx is zero-based */
@@ -2168,6 +2287,7 @@ static int thermal_read(char *p)
 static struct ibm_struct thermal_driver_data = {
 	.name = "thermal",
 	.read = thermal_read,
+	.exit = thermal_exit,
 };
 
 /*************************************************************************
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index a9feb53..e833ff3 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -38,6 +38,7 @@
 #include <linux/fb.h>
 #include <linux/platform_device.h>
 #include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
 #include <asm/uaccess.h>
 
 #include <linux/dmi.h>
@@ -467,6 +468,7 @@ enum thermal_access_mode {
 enum { /* TPACPI_THERMAL_TPEC_* */
 	TP_EC_THERMAL_TMP0 = 0x78,	/* ACPI EC regs TMP 0..7 */
 	TP_EC_THERMAL_TMP8 = 0xC0,	/* ACPI EC regs TMP 8..15 */
+	TP_EC_THERMAL_TMP_NA = -128,	/* ACPI EC sensor not available */
 };
 
 #define TPACPI_MAX_THERMAL_SENSORS 16	/* Max thermal sensors supported */
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 073/105] ACPI: thinkpad-acpi: add sysfs support to fan subdriver
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Export sysfs attributes to monitor and control the internal thinkpad fan
(some thinkpads have more than one fan, but thinkpad-acpi doesn't support
the second fan yet).  The sysfs interface follows the hwmon design guide
for fan devices.

Also, fix some stray "thermal" files in the fan procfs description that
have been there forever, and officially support "full-speed" as the name
for the PWM-disabled state of the fan controller to keep it in line with
the hwmon interface.  It is much better a name for that mode than the
unobvious "disengaged" anyway.  Change the procfs interface to also accept
full-speed as a fan level, but still report it as disengaged for backwards
compatibility.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 Documentation/thinkpad-acpi.txt |  157 +++++++++++++------
 drivers/misc/thinkpad_acpi.c    |  326 ++++++++++++++++++++++++++++++++++++---
 drivers/misc/thinkpad_acpi.h    |    6 +
 3 files changed, 415 insertions(+), 74 deletions(-)

diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt
index 80c0bf2..339ce21 100644
--- a/Documentation/thinkpad-acpi.txt
+++ b/Documentation/thinkpad-acpi.txt
@@ -642,8 +642,11 @@ distinct. The unmute the volume after the mute command, use either the
 up or down command (the level command will not unmute the volume).
 The current volume level and mute state is shown in the file.
 
-EXPERIMENTAL: fan speed, fan enable/disable -- /proc/acpi/ibm/fan
------------------------------------------------------------------
+EXPERIMENTAL: fan speed, fan enable/disable
+-------------------------------------------
+
+procfs: /proc/acpi/ibm/fan
+sysfs device attributes: (hwmon) fan_input, pwm1, pwm1_enable
 
 This feature is marked EXPERIMENTAL because the implementation
 directly accesses hardware registers and may not work as expected. USE
@@ -656,27 +659,26 @@ from the hardware registers of the embedded controller.  This is known
 to work on later R, T and X series ThinkPads but may show a bogus
 value on other models.
 
-Most ThinkPad fans work in "levels".  Level 0 stops the fan.  The higher
-the level, the higher the fan speed, although adjacent levels often map
-to the same fan speed.  7 is the highest level, where the fan reaches
-the maximum recommended speed.  Level "auto" means the EC changes the
-fan level according to some internal algorithm, usually based on
-readings from the thermal sensors.  Level "disengaged" means the EC
-disables the speed-locked closed-loop fan control, and drives the fan as
-fast as it can go, which might exceed hardware limits, so use this level
-with caution.
+Fan levels:
 
-The fan usually ramps up or down slowly from one speed to another,
-and it is normal for the EC to take several seconds to react to fan
-commands.
+Most ThinkPad fans work in "levels" at the firmware interface.  Level 0
+stops the fan.  The higher the level, the higher the fan speed, although
+adjacent levels often map to the same fan speed.  7 is the highest
+level, where the fan reaches the maximum recommended speed.
 
-The fan may be enabled or disabled with the following commands:
+Level "auto" means the EC changes the fan level according to some
+internal algorithm, usually based on readings from the thermal sensors.
 
-	echo enable  >/proc/acpi/ibm/fan
-	echo disable >/proc/acpi/ibm/fan
+There is also a "full-speed" level, also known as "disengaged" level.
+In this level, the EC disables the speed-locked closed-loop fan control,
+and drives the fan as fast as it can go, which might exceed hardware
+limits, so use this level with caution.
 
-Placing a fan on level 0 is the same as disabling it.  Enabling a fan
-will try to place it in a safe level if it is too slow or disabled.
+The fan usually ramps up or down slowly from one speed to another, and
+it is normal for the EC to take several seconds to react to fan
+commands.  The full-speed level may take up to two minutes to ramp up to
+maximum speed, and in some ThinkPads, the tachometer readings go stale
+while the EC is transitioning to the full-speed level.
 
 WARNING WARNING WARNING: do not leave the fan disabled unless you are
 monitoring all of the temperature sensor readings and you are ready to
@@ -694,48 +696,101 @@ fan is turned off when the CPU temperature drops to 49 degrees and the
 HDD temperature drops to 41 degrees.  These thresholds cannot
 currently be controlled.
 
+The ThinkPad's ACPI DSDT code will reprogram the fan on its own when
+certain conditions are met.  It will override any fan programming done
+through thinkpad-acpi.
+
+The thinkpad-acpi kernel driver can be programmed to revert the fan
+level to a safe setting if userspace does not issue one of the procfs
+fan commands: "enable", "disable", "level" or "watchdog", or if there
+are no writes to pwm1_enable (or to pwm1 *if and only if* pwm1_enable is
+set to 1, manual mode) within a configurable amount of time of up to
+120 seconds.  This functionality is called fan safety watchdog.
+
+Note that the watchdog timer stops after it enables the fan.  It will be
+rearmed again automatically (using the same interval) when one of the
+above mentioned fan commands is received.  The fan watchdog is,
+therefore, not suitable to protect against fan mode changes made through
+means other than the "enable", "disable", and "level" procfs fan
+commands, or the hwmon fan control sysfs interface.
+
+Procfs notes:
+
+The fan may be enabled or disabled with the following commands:
+
+	echo enable  >/proc/acpi/ibm/fan
+	echo disable >/proc/acpi/ibm/fan
+
+Placing a fan on level 0 is the same as disabling it.  Enabling a fan
+will try to place it in a safe level if it is too slow or disabled.
+
 The fan level can be controlled with the command:
 
-	echo 'level <level>' > /proc/acpi/ibm/thermal
+	echo 'level <level>' > /proc/acpi/ibm/fan
 
-Where <level> is an integer from 0 to 7, or one of the words "auto"
-or "disengaged" (without the quotes).  Not all ThinkPads support the
-"auto" and "disengaged" levels.
+Where <level> is an integer from 0 to 7, or one of the words "auto" or
+"full-speed" (without the quotes).  Not all ThinkPads support the "auto"
+and "full-speed" levels.  The driver accepts "disengaged" as an alias for
+"full-speed", and reports it as "disengaged" for backwards
+compatibility.
 
 On the X31 and X40 (and ONLY on those models), the fan speed can be
-controlled to a certain degree. Once the fan is running, it can be
+controlled to a certain degree.  Once the fan is running, it can be
 forced to run faster or slower with the following command:
 
-	echo 'speed <speed>' > /proc/acpi/ibm/thermal
+	echo 'speed <speed>' > /proc/acpi/ibm/fan
 
-The sustainable range of fan speeds on the X40 appears to be from
-about 3700 to about 7350. Values outside this range either do not have
-any effect or the fan speed eventually settles somewhere in that
-range. The fan cannot be stopped or started with this command.
+The sustainable range of fan speeds on the X40 appears to be from about
+3700 to about 7350. Values outside this range either do not have any
+effect or the fan speed eventually settles somewhere in that range.  The
+fan cannot be stopped or started with this command.  This functionality
+is incomplete, and not available through the sysfs interface.
 
-The ThinkPad's ACPI DSDT code will reprogram the fan on its own when
-certain conditions are met.  It will override any fan programming done
-through thinkpad-acpi.
+To program the safety watchdog, use the "watchdog" command.
+
+	echo 'watchdog <interval in seconds>' > /proc/acpi/ibm/fan
+
+If you want to disable the watchdog, use 0 as the interval.
+
+Sysfs notes:
+
+The sysfs interface follows the hwmon subsystem guidelines for the most
+part, and the exception is the fan safety watchdog.
+
+hwmon device attribute pwm1_enable:
+	0: PWM offline (fan is set to full-speed mode)
+	1: Manual PWM control (use pwm1 to set fan level)
+	2: Hardware PWM control (EC "auto" mode)
+	3: reserved (Software PWM control, not implemented yet)
+
+	Modes 0 and 2 are not supported by all ThinkPads, and the driver
+	is not always able to detect this.  If it does know a mode is
+	unsupported, it will return -EINVAL.
+
+hwmon device attribute pwm1:
+	Fan level, scaled from the firmware values of 0-7 to the hwmon
+	scale of 0-255.  0 means fan stopped, 255 means highest normal
+	speed (level 7).
+
+	This attribute only commands the fan if pmw1_enable is set to 1
+	(manual PWM control).
+
+hwmon device attribute fan1_input:
+	Fan tachometer reading, in RPM.  May go stale on certain
+	ThinkPads while the EC transitions the PWM to offline mode,
+	which can take up to two minutes.  May return rubbish on older
+	ThinkPads.
+
+driver attribute fan_watchdog:
+	Fan safety watchdog timer interval, in seconds.  Minimum is
+	1 second, maximum is 120 seconds.  0 disables the watchdog.
+
+To stop the fan: set pwm1 to zero, and pwm1_enable to 1.
+
+To start the fan in a safe mode: set pwm1_enable to 2.  If that fails
+with ENOTSUP, set it to 1 and set pwm1 to at least 128 (255 would be the
+safest choice, though).
 
-The thinkpad-acpi kernel driver can be programmed to revert the fan
-level to a safe setting if userspace does not issue one of the fan
-commands: "enable", "disable", "level" or "watchdog" within a
-configurable ammount of time.  To do this, use the "watchdog" command.
-
-	echo 'watchdog <interval>' > /proc/acpi/ibm/fan
-
-Interval is the ammount of time in seconds to wait for one of the
-above mentioned fan commands before reseting the fan level to a safe
-one.  If set to zero, the watchdog is disabled (default).  When the
-watchdog timer runs out, it does the exact equivalent of the "enable"
-fan command.
-
-Note that the watchdog timer stops after it enables the fan.  It will
-be rearmed again automatically (using the same interval) when one of
-the above mentioned fan commands is received.  The fan watchdog is,
-therefore, not suitable to protect against fan mode changes made
-through means other than the "enable", "disable", and "level" fan
-commands.
 
 EXPERIMENTAL: WAN -- /proc/acpi/ibm/wan
 ---------------------------------------
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index d5526e8..a4d7ee4 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -2695,6 +2695,7 @@ static enum fan_control_access_mode fan_control_access_mode;
 static enum fan_control_commands fan_control_commands;
 
 static u8 fan_control_initial_status;
+static u8 fan_control_desired_level;
 
 static void fan_watchdog_fire(struct work_struct *ignored);
 static int fan_watchdog_maxinterval;
@@ -2708,8 +2709,222 @@ IBM_HANDLE(sfan, ec, "SFAN",	/* 570 */
 	   "JFNS",		/* 770x-JL */
 	   );			/* all others */
 
+/*
+ * SYSFS fan layout: hwmon compatible (device)
+ *
+ * pwm*_enable:
+ * 	0: "disengaged" mode
+ * 	1: manual mode
+ * 	2: native EC "auto" mode (recommended, hardware default)
+ *
+ * pwm*: set speed in manual mode, ignored otherwise.
+ * 	0 is level 0; 255 is level 7. Intermediate points done with linear
+ * 	interpolation.
+ *
+ * fan*_input: tachometer reading, RPM
+ *
+ *
+ * SYSFS fan layout: extensions
+ *
+ * fan_watchdog (driver):
+ * 	fan watchdog interval in seconds, 0 disables (default), max 120
+ */
+
+/* sysfs fan pwm1_enable ----------------------------------------------- */
+static ssize_t fan_pwm1_enable_show(struct device *dev,
+				    struct device_attribute *attr,
+				    char *buf)
+{
+	int res, mode;
+	u8 status;
+
+	res = fan_get_status_safe(&status);
+	if (res)
+		return res;
+
+	if (unlikely(tp_features.fan_ctrl_status_undef)) {
+		if (status != fan_control_initial_status) {
+			tp_features.fan_ctrl_status_undef = 0;
+		} else {
+			/* Return most likely status. In fact, it
+			 * might be the only possible status */
+			status = TP_EC_FAN_AUTO;
+		}
+	}
+
+	if (status & TP_EC_FAN_FULLSPEED) {
+		mode = 0;
+	} else if (status & TP_EC_FAN_AUTO) {
+		mode = 2;
+	} else
+		mode = 1;
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", mode);
+}
+
+static ssize_t fan_pwm1_enable_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	unsigned long t;
+	int res, level;
+
+	if (parse_strtoul(buf, 2, &t))
+		return -EINVAL;
+
+	switch (t) {
+	case 0:
+		level = TP_EC_FAN_FULLSPEED;
+		break;
+	case 1:
+		level = TPACPI_FAN_LAST_LEVEL;
+		break;
+	case 2:
+		level = TP_EC_FAN_AUTO;
+		break;
+	case 3:
+		/* reserved for software-controlled auto mode */
+		return -ENOSYS;
+	default:
+		return -EINVAL;
+	}
+
+	res = fan_set_level_safe(level);
+	if (res < 0)
+		return res;
+
+	fan_watchdog_reset();
+
+	return count;
+}
+
+static struct device_attribute dev_attr_fan_pwm1_enable =
+	__ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
+		fan_pwm1_enable_show, fan_pwm1_enable_store);
+
+/* sysfs fan pwm1 ------------------------------------------------------ */
+static ssize_t fan_pwm1_show(struct device *dev,
+			     struct device_attribute *attr,
+			     char *buf)
+{
+	int res;
+	u8 status;
+
+	res = fan_get_status_safe(&status);
+	if (res)
+		return res;
+
+	if (unlikely(tp_features.fan_ctrl_status_undef)) {
+		if (status != fan_control_initial_status) {
+			tp_features.fan_ctrl_status_undef = 0;
+		} else {
+			status = TP_EC_FAN_AUTO;
+		}
+	}
+
+	if ((status &
+	     (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) != 0)
+		status = fan_control_desired_level;
+
+	if (status > 7)
+		status = 7;
+
+	return snprintf(buf, PAGE_SIZE, "%u\n", (status * 255) / 7);
+}
+
+static ssize_t fan_pwm1_store(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *buf, size_t count)
+{
+	unsigned long s;
+	int rc;
+	u8 status, newlevel;
+
+	if (parse_strtoul(buf, 255, &s))
+		return -EINVAL;
+
+	/* scale down from 0-255 to 0-7 */
+	newlevel = (s >> 5) & 0x07;
+
+	rc = mutex_lock_interruptible(&fan_mutex);
+	if (rc < 0)
+		return rc;
+
+	rc = fan_get_status(&status);
+	if (!rc && (status &
+		    (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) {
+		rc = fan_set_level(newlevel);
+		if (!rc)
+			fan_update_desired_level(newlevel);
+		fan_watchdog_reset();
+	}
+
+	mutex_unlock(&fan_mutex);
+	return (rc)? rc : count;
+}
+
+static struct device_attribute dev_attr_fan_pwm1 =
+	__ATTR(pwm1, S_IWUSR | S_IRUGO,
+		fan_pwm1_show, fan_pwm1_store);
+
+/* sysfs fan fan1_input ------------------------------------------------ */
+static ssize_t fan_fan1_input_show(struct device *dev,
+			   struct device_attribute *attr,
+			   char *buf)
+{
+	int res;
+	unsigned int speed;
+
+	res = fan_get_speed(&speed);
+	if (res < 0)
+		return res;
+
+	return snprintf(buf, PAGE_SIZE, "%u\n", speed);
+}
+
+static struct device_attribute dev_attr_fan_fan1_input =
+	__ATTR(fan1_input, S_IRUGO,
+		fan_fan1_input_show, NULL);
+
+/* sysfs fan fan_watchdog (driver) ------------------------------------- */
+static ssize_t fan_fan_watchdog_show(struct device_driver *drv,
+				     char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n", fan_watchdog_maxinterval);
+}
+
+static ssize_t fan_fan_watchdog_store(struct device_driver *drv,
+				      const char *buf, size_t count)
+{
+	unsigned long t;
+
+	if (parse_strtoul(buf, 120, &t))
+		return -EINVAL;
+
+	fan_watchdog_maxinterval = t;
+	fan_watchdog_reset();
+
+	return count;
+}
+
+static DRIVER_ATTR(fan_watchdog, S_IWUSR | S_IRUGO,
+		fan_fan_watchdog_show, fan_fan_watchdog_store);
+
+/* --------------------------------------------------------------------- */
+static struct attribute *fan_attributes[] = {
+	&dev_attr_fan_pwm1_enable.attr, &dev_attr_fan_pwm1.attr,
+	&dev_attr_fan_fan1_input.attr,
+	NULL
+};
+
+static const struct attribute_group fan_attr_group = {
+	.attrs = fan_attributes,
+};
+
 static int __init fan_init(struct ibm_init_struct *iibm)
 {
+	int rc;
+
 	vdbg_printk(TPACPI_DBG_INIT, "initializing fan subdriver\n");
 
 	mutex_init(&fan_mutex);
@@ -2718,6 +2933,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)
 	fan_control_commands = 0;
 	fan_watchdog_maxinterval = 0;
 	tp_features.fan_ctrl_status_undef = 0;
+	fan_control_desired_level = 7;
 
 	IBM_ACPIHANDLE_INIT(fans);
 	IBM_ACPIHANDLE_INIT(gfan);
@@ -2796,9 +3012,36 @@ static int __init fan_init(struct ibm_init_struct *iibm)
 		  fan_control_access_mode != TPACPI_FAN_WR_NONE),
 		fan_status_access_mode, fan_control_access_mode);
 
-	return (fan_status_access_mode != TPACPI_FAN_NONE ||
-	        fan_control_access_mode != TPACPI_FAN_WR_NONE)?
-			0 : 1;
+	/* update fan_control_desired_level */
+	if (fan_status_access_mode != TPACPI_FAN_NONE)
+		fan_get_status_safe(NULL);
+
+	if (fan_status_access_mode != TPACPI_FAN_NONE ||
+	    fan_control_access_mode != TPACPI_FAN_WR_NONE) {
+		rc = sysfs_create_group(&tpacpi_pdev->dev.kobj,
+					 &fan_attr_group);
+		if (!(rc < 0))
+			rc = driver_create_file(&tpacpi_pdriver.driver,
+					&driver_attr_fan_watchdog);
+		if (rc < 0)
+			return rc;
+		return 0;
+	} else
+		return 1;
+}
+
+/*
+ * Call with fan_mutex held
+ */
+static void fan_update_desired_level(u8 status)
+{
+	if ((status &
+	     (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) {
+		if (status > 7)
+			fan_control_desired_level = 7;
+		else
+			fan_control_desired_level = status;
+	}
 }
 
 static int fan_get_status(u8 *status)
@@ -2837,9 +3080,33 @@ static int fan_get_status(u8 *status)
 	return 0;
 }
 
+static int fan_get_status_safe(u8 *status)
+{
+	int rc;
+	u8 s;
+
+	rc = mutex_lock_interruptible(&fan_mutex);
+	if (rc < 0)
+		return rc;
+	rc = fan_get_status(&s);
+	if (!rc)
+		fan_update_desired_level(s);
+	mutex_unlock(&fan_mutex);
+
+	if (status)
+		*status = s;
+
+	return rc;
+}
+
 static void fan_exit(void)
 {
 	vdbg_printk(TPACPI_DBG_EXIT, "cancelling any pending fan watchdog tasks\n");
+
+	/* FIXME: can we really do this unconditionally? */
+	sysfs_remove_group(&tpacpi_pdev->dev.kobj, &fan_attr_group);
+	driver_remove_file(&tpacpi_pdriver.driver, &driver_attr_fan_watchdog);
+
 	cancel_delayed_work(&fan_watchdog_task);
 	flush_scheduled_work();
 }
@@ -2902,17 +3169,10 @@ static void fan_watchdog_reset(void)
 
 static int fan_set_level(int level)
 {
-	int res;
-
 	switch (fan_control_access_mode) {
 	case TPACPI_FAN_WR_ACPI_SFAN:
 		if (level >= 0 && level <= 7) {
-			res = mutex_lock_interruptible(&fan_mutex);
-			if (res < 0)
-				return res;
-			res = acpi_evalf(sfan_handle, NULL, NULL, "vd", level);
-			mutex_unlock(&fan_mutex);
-			if (!res)
+			if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level))
 				return -EIO;
 		} else
 			return -EINVAL;
@@ -2925,12 +3185,7 @@ static int fan_set_level(int level)
 		    ((level < 0) || (level > 7)))
 			return -EINVAL;
 
-		res = mutex_lock_interruptible(&fan_mutex);
-		if (res < 0)
-			return res;
-		res = acpi_ec_write(fan_status_offset, level);
-		mutex_unlock(&fan_mutex);
-		if (!res)
+		if (!acpi_ec_write(fan_status_offset, level))
 			return -EIO;
 		else
 			tp_features.fan_ctrl_status_undef = 0;
@@ -2942,6 +3197,25 @@ static int fan_set_level(int level)
 	return 0;
 }
 
+static int fan_set_level_safe(int level)
+{
+	int rc;
+
+	rc = mutex_lock_interruptible(&fan_mutex);
+	if (rc < 0)
+		return rc;
+
+	if (level == TPACPI_FAN_LAST_LEVEL)
+		level = fan_control_desired_level;
+
+	rc = fan_set_level(level);
+	if (!rc)
+		fan_update_desired_level(level);
+
+	mutex_unlock(&fan_mutex);
+	return rc;
+}
+
 static int fan_set_enable(void)
 {
 	u8 s;
@@ -3009,19 +3283,24 @@ static int fan_set_disable(void)
 	case TPACPI_FAN_WR_TPEC:
 		if (!acpi_ec_write(fan_status_offset, 0x00))
 			rc = -EIO;
-		else
+		else {
+			fan_control_desired_level = 0;
 			tp_features.fan_ctrl_status_undef = 0;
+		}
 		break;
 
 	case TPACPI_FAN_WR_ACPI_SFAN:
 		if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", 0x00))
 			rc = -EIO;
+		else
+			fan_control_desired_level = 0;
 		break;
 
 	default:
 		rc = -ENXIO;
 	}
 
+
 	mutex_unlock(&fan_mutex);
 	return rc;
 }
@@ -3063,7 +3342,7 @@ static int fan_read(char *p)
 	switch (fan_status_access_mode) {
 	case TPACPI_FAN_RD_ACPI_GFAN:
 		/* 570, 600e/x, 770e, 770x */
-		if ((rc = fan_get_status(&status)) < 0)
+		if ((rc = fan_get_status_safe(&status)) < 0)
 			return rc;
 
 		len += sprintf(p + len, "status:\t\t%s\n"
@@ -3073,7 +3352,7 @@ static int fan_read(char *p)
 
 	case TPACPI_FAN_RD_TPEC:
 		/* all except 570, 600e/x, 770e, 770x */
-		if ((rc = fan_get_status(&status)) < 0)
+		if ((rc = fan_get_status_safe(&status)) < 0)
 			return rc;
 
 		if (unlikely(tp_features.fan_ctrl_status_undef)) {
@@ -3117,7 +3396,7 @@ static int fan_read(char *p)
 
 		default:
 			len += sprintf(p + len, " (<level> is 0-7, "
-				       "auto, disengaged)\n");
+				       "auto, disengaged, full-speed)\n");
 			break;
 		}
 	}
@@ -3140,12 +3419,13 @@ static int fan_write_cmd_level(const char *cmd, int *rc)
 
 	if (strlencmp(cmd, "level auto") == 0)
 		level = TP_EC_FAN_AUTO;
-	else if (strlencmp(cmd, "level disengaged") == 0)
+	else if ((strlencmp(cmd, "level disengaged") == 0) |
+	         (strlencmp(cmd, "level full-speed") == 0))
 		level = TP_EC_FAN_FULLSPEED;
 	else if (sscanf(cmd, "level %d", &level) != 1)
 		return 0;
 
-	if ((*rc = fan_set_level(level)) == -ENXIO)
+	if ((*rc = fan_set_level_safe(level)) == -ENXIO)
 		printk(IBM_ERR "level command accepted for unsupported "
 		       "access mode %d", fan_control_access_mode);
 
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index e833ff3..2fe4d61 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -349,6 +349,8 @@ enum {					/* Fan control constants */
 
 	TP_EC_FAN_FULLSPEED = 0x40,	/* EC fan mode: full speed */
 	TP_EC_FAN_AUTO	    = 0x80,	/* EC fan mode: auto fan control */
+
+	TPACPI_FAN_LAST_LEVEL = 0x100,	/* Use cached last-seen fan level */
 };
 
 enum fan_status_access_mode {
@@ -375,6 +377,7 @@ static enum fan_status_access_mode fan_status_access_mode;
 static enum fan_control_access_mode fan_control_access_mode;
 static enum fan_control_commands fan_control_commands;
 static u8 fan_control_initial_status;
+static u8 fan_control_desired_level;
 static int fan_watchdog_maxinterval;
 
 struct mutex fan_mutex;
@@ -384,10 +387,13 @@ static acpi_handle fans_handle, gfan_handle, sfan_handle;
 static int fan_init(struct ibm_init_struct *iibm);
 static void fan_exit(void);
 static int fan_get_status(u8 *status);
+static int fan_get_status_safe(u8 *status);
 static int fan_get_speed(unsigned int *speed);
+static void fan_update_desired_level(u8 status);
 static void fan_watchdog_fire(struct work_struct *ignored);
 static void fan_watchdog_reset(void);
 static int fan_set_level(int level);
+static int fan_set_level_safe(int level);
 static int fan_set_enable(void);
 static int fan_set_disable(void);
 static int fan_set_speed(int speed);
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 074/105] ACPI: thinkpad-acpi: add a safety net for TPEC fan control mode
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

The Linux ThinkPad community is not positive that all ThinkPads that do
HFSP EC fan control do implement full-speed and auto modes, some of the
earlier ones supporting HFSP might not.

If the EC ignores the AUTO or FULL-SPEED bits, it will pay attention to the
lower three bits that set the fan level.  And as thinkpad-acpi was leaving
these set to zero, it would stop(!) the fan, which is Not A Good Thing.

So, as a safety net, we now make sure to also set the fan level part of the
HFSP register to speed 7 for full-speed, and a minimum of speed 4 for auto
mode.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |   16 ++++++++++++----
 1 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index a4d7ee4..79abc68 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -3185,6 +3185,13 @@ static int fan_set_level(int level)
 		    ((level < 0) || (level > 7)))
 			return -EINVAL;
 
+		/* safety net should the EC not support AUTO
+		 * or FULLSPEED mode bits and just ignore them */
+		if (level & TP_EC_FAN_FULLSPEED)
+			level |= 7;	/* safety min speed 7 */
+		else if (level & TP_EC_FAN_FULLSPEED)
+			level |= 4;	/* safety min speed 4 */
+
 		if (!acpi_ec_write(fan_status_offset, level))
 			return -EIO;
 		else
@@ -3233,8 +3240,10 @@ static int fan_set_enable(void)
 			break;
 
 		/* Don't go out of emergency fan mode */
-		if (s != 7)
-			s = TP_EC_FAN_AUTO;
+		if (s != 7) {
+			s &= 0x07;
+			s |= TP_EC_FAN_AUTO | 4; /* min fan speed 4 */
+		}
 
 		if (!acpi_ec_write(fan_status_offset, s))
 			rc = -EIO;
@@ -3252,8 +3261,7 @@ static int fan_set_enable(void)
 		s &= 0x07;
 
 		/* Set fan to at least level 4 */
-		if (s < 4)
-			s = 4;
+		s |= 4;
 
 		if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", s))
 			rc= -EIO;
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 075/105] ACPI: thinkpad-acpi: add sysfs support to the cmos command subdriver
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Add sysfs attributes to send ThinkPad CMOS commands.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 Documentation/thinkpad-acpi.txt |   23 +++++++++++------------
 drivers/misc/thinkpad_acpi.c    |   33 +++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt
index 339ce21..352e8ae 100644
--- a/Documentation/thinkpad-acpi.txt
+++ b/Documentation/thinkpad-acpi.txt
@@ -378,23 +378,19 @@ supported. Use "eject2" instead of "eject" for the second bay.
 Note: the UltraBay eject support on the 600e/x, A22p and A3x is
 EXPERIMENTAL and may not work as expected. USE WITH CAUTION!
 
-CMOS control -- /proc/acpi/ibm/cmos
------------------------------------
+CMOS control
+------------
+
+procfs: /proc/acpi/ibm/cmos
+sysfs device attribute: cmos_command
 
 This feature is used internally by the ACPI firmware to control the
 ThinkLight on most newer ThinkPad models. It may also control LCD
 brightness, sounds volume and more, but only on some models.
 
-The commands are non-negative integer numbers:
-
-	echo 0 >/proc/acpi/ibm/cmos
-	echo 1 >/proc/acpi/ibm/cmos
-	echo 2 >/proc/acpi/ibm/cmos
-	...
-
-The range of valid numbers is 0 to 21, but not all have an effect and
-the behavior varies from model to model. Here is the behavior on the
-X40 (tpb is the ThinkPad Buttons utility):
+The range of valid cmos command numbers is 0 to 21, but not all have an
+effect and the behavior varies from model to model.  Here is the behavior
+on the X40 (tpb is the ThinkPad Buttons utility):
 
 	0 - no effect but tpb reports "Volume down"
 	1 - no effect but tpb reports "Volume up"
@@ -407,6 +403,9 @@ X40 (tpb is the ThinkPad Buttons utility):
 	13 - ThinkLight off
 	14 - no effect but tpb reports ThinkLight status change
 
+The cmos command interface is prone to firmware split-brain problems, as
+in newer ThinkPads it is just a compatibility layer.
+
 LED control -- /proc/acpi/ibm/led
 ---------------------------------
 
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 79abc68..ba749df 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -1743,8 +1743,30 @@ static struct ibm_struct bay_driver_data = {
  * CMOS subdriver
  */
 
+/* sysfs cmos_command -------------------------------------------------- */
+static ssize_t cmos_command_store(struct device *dev,
+			    struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	unsigned long cmos_cmd;
+	int res;
+
+	if (parse_strtoul(buf, 21, &cmos_cmd))
+		return -EINVAL;
+
+	res = issue_thinkpad_cmos_command(cmos_cmd);
+	return (res)? res : count;
+}
+
+static struct device_attribute dev_attr_cmos_command =
+	__ATTR(cmos_command, S_IWUSR, NULL, cmos_command_store);
+
+/* --------------------------------------------------------------------- */
+
 static int __init cmos_init(struct ibm_init_struct *iibm)
 {
+	int res;
+
 	vdbg_printk(TPACPI_DBG_INIT,
 		"initializing cmos commands subdriver\n");
 
@@ -1752,9 +1774,19 @@ static int __init cmos_init(struct ibm_init_struct *iibm)
 
 	vdbg_printk(TPACPI_DBG_INIT, "cmos commands are %s\n",
 		str_supported(cmos_handle != NULL));
+
+	res = device_create_file(&tpacpi_pdev->dev, &dev_attr_cmos_command);
+	if (res)
+		return res;
+
 	return (cmos_handle)? 0 : 1;
 }
 
+static void cmos_exit(void)
+{
+	device_remove_file(&tpacpi_pdev->dev, &dev_attr_cmos_command);
+}
+
 static int cmos_read(char *p)
 {
 	int len = 0;
@@ -1795,6 +1827,7 @@ static struct ibm_struct cmos_driver_data = {
 	.name = "cmos",
 	.read = cmos_read,
 	.write = cmos_write,
+	.exit = cmos_exit,
 };
 
 /*************************************************************************
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 076/105] ACPI: thinkpad-acpi: update brightness sysfs interface support
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Update the brightness sysfs interface (done through the backlight class) to
be in line with the rest of the thinkpad-acpi driver.

This renames the incorrect, un-obvious, and clash-prone name of "ibm" for
the backlight device to a much more fitting and descriptive
"thinkpad_screen".  This is something I wanted to do for quite a while...

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 Documentation/thinkpad-acpi.txt |   52 ++++++++++++++++++++++++++++++++++----
 drivers/misc/thinkpad_acpi.c    |    5 ++-
 drivers/misc/thinkpad_acpi.h    |    2 +
 3 files changed, 51 insertions(+), 8 deletions(-)

diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt
index 352e8ae..eab4997 100644
--- a/Documentation/thinkpad-acpi.txt
+++ b/Documentation/thinkpad-acpi.txt
@@ -611,19 +611,59 @@ registers contain the current battery capacity, etc. If you experiment
 with this, do send me your results (including some complete dumps with
 a description of the conditions when they were taken.)
 
-LCD brightness control -- /proc/acpi/ibm/brightness
----------------------------------------------------
+LCD brightness control
+----------------------
+
+procfs: /proc/acpi/ibm/brightness
+sysfs backlight device "thinkpad_screen"
 
 This feature allows software control of the LCD brightness on ThinkPad
-models which don't have a hardware brightness slider. The available
-commands are:
+models which don't have a hardware brightness slider.
+
+It has some limitations: the LCD backlight cannot be actually turned on or off
+by this interface, and in many ThinkPad models, the "dim while on battery"
+functionality will be enabled by the BIOS when this interface is used, and
+cannot be controlled.
+
+The backlight control has eight levels, ranging from 0 to 7.  Some of the
+levels may not be distinct.
+
+Procfs notes:
+
+	The available commands are:
 
 	echo up   >/proc/acpi/ibm/brightness
 	echo down >/proc/acpi/ibm/brightness
 	echo 'level <level>' >/proc/acpi/ibm/brightness
 
-The <level> number range is 0 to 7, although not all of them may be
-distinct. The current brightness level is shown in the file.
+Sysfs notes:
+
+The interface is implemented through the backlight sysfs class, which is poorly
+documented at this time.
+
+Locate the thinkpad_screen device under /sys/class/backlight, and inside it
+there will be the following attributes:
+
+	max_brightness:
+		Reads the maximum brightness the hardware can be set to.
+		The minimum is always zero.
+
+	actual_brightness:
+		Reads what brightness the screen is set to at this instant.
+
+	brightness:
+		Writes request the driver to change brightness to the given
+		value.  Reads will tell you what brightness the driver is trying
+		to set the display to when "power" is set to zero and the display
+		has not been dimmed by a kernel power management event.
+
+	power:
+		power management mode, where 0 is "display on", and 1 to 3 will
+		dim the display backlight to brightness level 0 because
+		thinkpad-acpi cannot really turn the backlight off.  Kernel
+		power management events can temporarily increase the current
+		power management level, i.e. they can dim the display.
+
 
 Volume control -- /proc/acpi/ibm/volume
 ---------------------------------------
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index ba749df..c0a023c 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -2414,8 +2414,9 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
 	if (b < 0)
 		return b;
 
-	ibm_backlight_device = backlight_device_register("ibm", NULL, NULL,
-							 &ibm_backlight_data);
+	ibm_backlight_device = backlight_device_register(
+					TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL,
+					&ibm_backlight_data);
 	if (IS_ERR(ibm_backlight_device)) {
 		printk(IBM_ERR "Could not register backlight device\n");
 		return PTR_ERR(ibm_backlight_device);
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 2fe4d61..8348fc6 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -296,6 +296,8 @@ static int bluetooth_write(char *buf);
  * Brightness (backlight) subdriver
  */
 
+#define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen"
+
 static struct backlight_device *ibm_backlight_device;
 static int brightness_offset = 0x31;
 
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 077/105] ACPI: remove duplicate include
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Ray Lee, Andrew Morton, Len Brown

From: Ray Lee <ray-lk@madrabbit.org>

Thomas's patch for including <asm/apic.h> for x86 UP builds came into
Linus's tree from two different directions, both of which were merged.
This reverts the latter, yanking out the duplicate #include and comment.

Signed-off-by: Ray Lee <ray-lk@madrabbit.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/processor_idle.c |    8 --------
 1 files changed, 0 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index cdf7894..ae0654c 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -51,14 +51,6 @@
 #include <asm/apic.h>
 #endif
 
-/*
- * Include the apic definitions for x86 to have the APIC timer related defines
- * available also for UP (on SMP it gets magically included via linux/smp.h).
- */
-#ifdef CONFIG_X86
-#include <asm/apic.h>
-#endif
-
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 078/105] ACPI: Remove duplicate definitions for _STA bits
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Bjorn Helgaas, Andrew Morton, Len Brown

From: Bjorn Helgaas <bjorn.helgaas@hp.com>

No need to duplicate the existing definitions in include/acpi/actypes.h.

syntax only -- no functional change.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/acpi_memhotplug.c |   13 ++++---------
 drivers/acpi/container.c       |    6 ++----
 drivers/acpi/processor_core.c  |    4 +---
 3 files changed, 7 insertions(+), 16 deletions(-)

diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index c261726..e65628a 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -44,11 +44,6 @@ MODULE_AUTHOR("Naveen B S <naveen.b.s@intel.com>");
 MODULE_DESCRIPTION("Hotplug Mem Driver");
 MODULE_LICENSE("GPL");
 
-/* ACPI _STA method values */
-#define ACPI_MEMORY_STA_PRESENT		(0x00000001UL)
-#define ACPI_MEMORY_STA_ENABLED		(0x00000002UL)
-#define ACPI_MEMORY_STA_FUNCTIONAL	(0x00000008UL)
-
 /* Memory Device States */
 #define MEMORY_INVALID_STATE	0
 #define MEMORY_POWER_ON_STATE	1
@@ -204,9 +199,9 @@ static int acpi_memory_check_device(struct acpi_memory_device *mem_device)
 	 * Check for device status. Device should be
 	 * present/enabled/functioning.
 	 */
-	if (!((current_status & ACPI_MEMORY_STA_PRESENT)
-	      && (current_status & ACPI_MEMORY_STA_ENABLED)
-	      && (current_status & ACPI_MEMORY_STA_FUNCTIONAL)))
+	if (!((current_status & ACPI_STA_DEVICE_PRESENT)
+	      && (current_status & ACPI_STA_DEVICE_ENABLED)
+	      && (current_status & ACPI_STA_DEVICE_FUNCTIONING)))
 		return -ENODEV;
 
 	return 0;
@@ -286,7 +281,7 @@ static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device)
 		return -ENODEV;
 
 	/* Check for device status.  Device should be disabled */
-	if (current_status & ACPI_MEMORY_STA_ENABLED)
+	if (current_status & ACPI_STA_DEVICE_ENABLED)
 		return -EINVAL;
 
 	return 0;
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 0930d94..0dd3bf7 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -49,8 +49,6 @@ MODULE_AUTHOR("Anil S Keshavamurthy");
 MODULE_DESCRIPTION("ACPI container driver");
 MODULE_LICENSE("GPL");
 
-#define ACPI_STA_PRESENT		(0x00000001)
-
 static int acpi_container_add(struct acpi_device *device);
 static int acpi_container_remove(struct acpi_device *device, int type);
 
@@ -75,13 +73,13 @@ static int is_device_present(acpi_handle handle)
 
 	status = acpi_get_handle(handle, "_STA", &temp);
 	if (ACPI_FAILURE(status))
-		return 1;	/* _STA not found, assmue device present */
+		return 1;	/* _STA not found, assume device present */
 
 	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
 	if (ACPI_FAILURE(status))
 		return 0;	/* Firmware error */
 
-	return ((sta & ACPI_STA_PRESENT) == ACPI_STA_PRESENT);
+	return ((sta & ACPI_STA_DEVICE_PRESENT) == ACPI_STA_DEVICE_PRESENT);
 }
 
 /*******************************************************************/
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 99d1516..f7de02a 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -70,8 +70,6 @@
 #define ACPI_PROCESSOR_LIMIT_USER	0
 #define ACPI_PROCESSOR_LIMIT_THERMAL	1
 
-#define ACPI_STA_PRESENT 0x00000001
-
 #define _COMPONENT		ACPI_PROCESSOR_COMPONENT
 ACPI_MODULE_NAME("processor_core");
 
@@ -779,7 +777,7 @@ static int is_processor_present(acpi_handle handle)
 
 
 	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
-	if (ACPI_FAILURE(status) || !(sta & ACPI_STA_PRESENT)) {
+	if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_PRESENT)) {
 		ACPI_EXCEPTION((AE_INFO, status, "Processor Device is not present"));
 		return 0;
 	}
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 079/105] ACPI: use _STA bit names rather than 0x0F
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Bjorn Helgaas, Andrew Morton, Len Brown

From: Bjorn Helgaas <bjorn.helgaas@hp.com>

Be explicit about what "device->status = 0x0F" really means.

syntax only.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/bus.c  |    4 +++-
 drivers/acpi/scan.c |    4 +++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index dd49ea0..e5084ec 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -103,7 +103,9 @@ int acpi_bus_get_status(struct acpi_device *device)
 	else if (device->parent)
 		device->status = device->parent->status;
 	else
-		STRUCT_TO_INT(device->status) = 0x0F;
+		STRUCT_TO_INT(device->status) =
+		    ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
+		    ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING;
 
 	if (device->status.functional && !device->status.present) {
 		printk(KERN_WARNING PREFIX "Device [%s] status [%08x]: "
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index bb0e0da..d80dd84 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1068,7 +1068,9 @@ acpi_add_single_object(struct acpi_device **child,
 		}
 		break;
 	default:
-		STRUCT_TO_INT(device->status) = 0x0F;
+		STRUCT_TO_INT(device->status) =
+		    ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
+		    ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING;
 		break;
 	}
 
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 080/105] ACPI: correct pathname in comment
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Daniel Walker, Andrew Morton, Len Brown

From: Daniel Walker <dwalker@mvista.com>

Signed-off-by: Daniel Walker <dwalker@mvista.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/clocksource/acpi_pm.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c
index 5ac309e..5cfcff5 100644
--- a/drivers/clocksource/acpi_pm.c
+++ b/drivers/clocksource/acpi_pm.c
@@ -26,7 +26,7 @@
 /*
  * The I/O port the PMTMR resides at.
  * The location is detected during setup_arch(),
- * in arch/i386/acpi/boot.c
+ * in arch/i386/kernel/acpi/boot.c
  */
 u32 pmtmr_ioport __read_mostly;
 
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 081/105] ACPI: word-smith kconfig help
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Borislav Petkov, Andrew Morton, Len Brown

From: Borislav Petkov <bbpetkov@yahoo.de>

Signed-off-by: <bbpetkov@yahoo.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/Kconfig |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index e2ce4a9..2a18d4c 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -85,8 +85,8 @@ config ACPI_PROCFS
 	depends on ACPI
 	default y
 	---help---
-	  Procfs interface for ACPI is made optional for back-compatible.
-	  As the same functions are duplicated in sysfs interface
+	  The Procfs interface for ACPI is made optional for backward compatibility.
+	  As the same functions are duplicated in the sysfs interface
 	  and this proc interface will be removed some time later,
 	  it's marked as deprecated.
 	  ( /proc/acpi/debug_layer && debug_level are deprecated by
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 082/105] ACPI: make /proc/acpi/wakeup more useful
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: David Brownell, David Brownell, Andrew Morton, Len Brown

From: David Brownell <david-b@pacbell.net>

This updates /proc/acpi/wakeup to be more informative, primarily by showing
the sysfs node associated with each wakeup-enabled device.  Example:

	Device	S-state	  Status   Sysfs node
	PCI0	  S4	 disabled  no-bus:pci0000:00
	PS2M	  S4	 disabled  pnp:00:05
	PS2K	  S4	 disabled  pnp:00:06
	UAR1	  S4	 disabled  pnp:00:08
	USB1	  S3	 disabled  pci:0000:00:03.0
	USB2	  S3	 disabled  pci:0000:00:03.1
	USB3	  S3	 disabled
	USB4	  S3	 disabled  pci:0000:00:03.3
	S139	  S4	 disabled
	LAN	  S4	 disabled  pci:0000:00:04.0
	MDM	  S4	 disabled
	AUD	  S4	 disabled  pci:0000:00:02.7
	SLPB	  S4	*enabled

Eventually this file should be removed, but until then it's almost the only
way we have to tell how the relevant ACPI tables are broken (and cope).  In
that example, two devices don't actually exist (USB3, S139), one can't issue
wakeup events (PCI0), and two seem harmlessly (?) confused (MDM and AUD are
the same PCI device, but it's the _modem_ that does wake-on-ring).

In particular, we need to be sure driver model nodes are properly hooked
up before we can get rid of this ACPI-only interface for wakeup events.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/sleep/proc.c |   16 +++++++++++++---
 1 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
index ccc11b3..2d912b7 100644
--- a/drivers/acpi/sleep/proc.c
+++ b/drivers/acpi/sleep/proc.c
@@ -350,21 +350,31 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
 {
 	struct list_head *node, *next;
 
-	seq_printf(seq, "Device	Sleep state	Status\n");
+	seq_printf(seq, "Device\tS-state\t  Status   Sysfs node\n");
 
 	spin_lock(&acpi_device_lock);
 	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
 		struct acpi_device *dev =
 		    container_of(node, struct acpi_device, wakeup_list);
+		struct device *ldev;
 
 		if (!dev->wakeup.flags.valid)
 			continue;
 		spin_unlock(&acpi_device_lock);
-		seq_printf(seq, "%4s	%4d		%s%8s\n",
+
+		ldev = acpi_get_physical_device(dev->handle);
+		seq_printf(seq, "%s\t  S%d\t%c%-8s  ",
 			   dev->pnp.bus_id,
 			   (u32) dev->wakeup.sleep_state,
-			   dev->wakeup.flags.run_wake ? "*" : "",
+			   dev->wakeup.flags.run_wake ? '*' : ' ',
 			   dev->wakeup.state.enabled ? "enabled" : "disabled");
+		if (ldev)
+			seq_printf(seq, "%s:%s",
+				ldev->bus ? ldev->bus->name : "no-bus",
+				ldev->bus_id);
+		seq_printf(seq, "\n");
+		put_device(ldev);
+
 		spin_lock(&acpi_device_lock);
 	}
 	spin_unlock(&acpi_device_lock);
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 083/105] ACPI: prevent ACPI quirk warning mass spamming in logs
@ 2007-04-29  4:51       ` Len Brown
  2007-04-29  9:58         ` Andi Kleen
  0 siblings, 1 reply; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Thierry Vignaud, Andi Kleen, Andrew Morton, Len Brown

From: Thierry Vignaud <tvignaud@mandriva.com>

The following patch prevent this warning to be displayed again & again (eg:
nine times on my NForce2 motherboard) and thus improve signal to noise
ratio in logs.

The ATI quirk below probably needs a similar "fix" but I don't have
the hardware to test.

Btw arch/x86_64/kernel/early-quirks.c::nvidia_bugs() would probably need to
be synced (but I don't have an x86_64 NVidia motherboard to boot test it).
Still it shows the usefullity of the recent x86 merge thread.

[akpm@linux-foundation.org: cleanup]
Signed-off-by: Thierry Vignaud <tvignaud@mandriva.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 arch/i386/kernel/acpi/earlyquirk.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c
index a7d22d9..fa3255a 100644
--- a/arch/i386/kernel/acpi/earlyquirk.c
+++ b/arch/i386/kernel/acpi/earlyquirk.c
@@ -22,11 +22,14 @@ static int __init nvidia_hpet_check(struct acpi_table_header *header)
 
 static int __init check_bridge(int vendor, int device)
 {
+	static int warned;
 #ifdef CONFIG_ACPI
 	/* According to Nvidia all timer overrides are bogus unless HPET
 	   is enabled. */
 	if (!acpi_use_timer_override && vendor == PCI_VENDOR_ID_NVIDIA) {
-		if (acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check)) {
+		if (!warned && acpi_table_parse(ACPI_SIG_HPET,
+						nvidia_hpet_check)) {
+			warned = 1;
 			acpi_skip_timer_override = 1;
 			  printk(KERN_INFO "Nvidia board "
                        "detected. Ignoring ACPI "
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 084/105] ACPI: Remove a warning about unused variable in !CONFIG_ACPI compilation.
@ 2007-04-29  4:51       ` Len Brown
  2007-04-29  9:59         ` Andi Kleen
  0 siblings, 1 reply; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Zachary Amsden, Andi Kleen, Andrew Morton, Len Brown

From: Zachary Amsden <zach@vmware.com>

Signed-off-by: Zachary Amsden <zach@vmware.com>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 arch/i386/kernel/acpi/earlyquirk.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c
index fa3255a..8f7efd3 100644
--- a/arch/i386/kernel/acpi/earlyquirk.c
+++ b/arch/i386/kernel/acpi/earlyquirk.c
@@ -22,8 +22,8 @@ static int __init nvidia_hpet_check(struct acpi_table_header *header)
 
 static int __init check_bridge(int vendor, int device)
 {
-	static int warned;
 #ifdef CONFIG_ACPI
+	static int warned;
 	/* According to Nvidia all timer overrides are bogus unless HPET
 	   is enabled. */
 	if (!acpi_use_timer_override && vendor == PCI_VENDOR_ID_NVIDIA) {
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 085/105] ACPICA: clear fields reserved before FADT r3
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Bob Moore, Len Brown

From: Bob Moore <robert.moore@intel.com>

Linux-2.6.21 stopped booting on a P4/HT because Linux
wrote the FADT.CST_CNT value to the SMI_CMD.
Apparently this stumbled over some SMM instability,
such as confusing SMM when invoking it from cpu1.

Linux did this because even though the r2 FADT reserves
the CST_CNT field, this BIOS set that field and Linux
used it.

Turns out that up through 2.6.20 we explicitly cleared
cst_control for r2 FADTs.  So here we go back to doing that,
plus also clear some additional fields that are reserved
until FADT r3.

http://bugzilla.kernel.org/show_bug.cgi?id=8346

Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/tables/tbfadt.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c
index 807c711..1db833e 100644
--- a/drivers/acpi/tables/tbfadt.c
+++ b/drivers/acpi/tables/tbfadt.c
@@ -347,6 +347,18 @@ static void acpi_tb_convert_fadt(void)
 		acpi_gbl_xpm1b_enable.space_id = acpi_gbl_FADT.xpm1a_event_block.space_id;
 
 	}
+
+	/*
+	 * For ACPI 1.0 FADTs, ensure that reserved fields (which should be zero)
+	 * are indeed zero. This will workaround BIOSs that inadvertently placed
+	 * values in these fields.
+	 */
+	if (acpi_gbl_FADT.header.revision < 3) {
+		acpi_gbl_FADT.preferred_profile = 0;
+		acpi_gbl_FADT.pstate_control = 0;
+		acpi_gbl_FADT.cst_control = 0;
+		acpi_gbl_FADT.boot_flags = 0;
+	}
 }
 
 /******************************************************************************
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 086/105] ACPI: thinkpad-acpi: add a fan-control feature master toggle
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Len Brown considers that an active by default fan control interface in
laptops may be too close to giving users enough rope.  There is a good
chance he is quite correct on this, especially if someone decides to use
that interface in applets and users are not aware of its risks.

This patch adds a master switch to thinkpad-acpi that enables or disables
the entire fan-control feature as a module parameter: "fan_control".  It
defaults to disabled.  Set it to non-zero to enable fan control.

Also, the patch removes the expermiental status from fan control, since it
is stable enough to not be called experimental, and the master switch makes
it safe enough to do so.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 Documentation/thinkpad-acpi.txt |   15 +++++++--------
 drivers/misc/thinkpad_acpi.c    |   30 +++++++++++++++++++++++++++++-
 drivers/misc/thinkpad_acpi.h    |    2 ++
 3 files changed, 38 insertions(+), 9 deletions(-)

diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt
index eab4997..bca50d7 100644
--- a/Documentation/thinkpad-acpi.txt
+++ b/Documentation/thinkpad-acpi.txt
@@ -38,7 +38,7 @@ detailed description):
 	- Experimental: embedded controller register dump
 	- LCD brightness control
 	- Volume control
-	- Experimental: fan speed, fan enable/disable
+	- Fan control and monitoring: fan speed, fan enable/disable
 	- Experimental: WAN enable and disable
 
 A compatibility table by model and feature is maintained on the web
@@ -681,21 +681,20 @@ distinct. The unmute the volume after the mute command, use either the
 up or down command (the level command will not unmute the volume).
 The current volume level and mute state is shown in the file.
 
-EXPERIMENTAL: fan speed, fan enable/disable
--------------------------------------------
+Fan control and monitoring: fan speed, fan enable/disable
+---------------------------------------------------------
 
 procfs: /proc/acpi/ibm/fan
 sysfs device attributes: (hwmon) fan_input, pwm1, pwm1_enable
 
-This feature is marked EXPERIMENTAL because the implementation
-directly accesses hardware registers and may not work as expected. USE
-WITH CAUTION! To use this feature, you need to supply the
-experimental=1 parameter when loading the module.
+NOTE NOTE NOTE: fan control operations are disabled by default for
+safety reasons.  To enable them, the module parameter "fan_control=1"
+must be given to thinkpad-acpi.
 
 This feature attempts to show the current fan speed, control mode and
 other fan data that might be available.  The speed is read directly
 from the hardware registers of the embedded controller.  This is known
-to work on later R, T and X series ThinkPads but may show a bogus
+to work on later R, T, X and Z series ThinkPads but may show a bogus
 value on other models.
 
 Fan levels:
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index c0a023c..7dc3a22 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -2935,6 +2935,9 @@ static ssize_t fan_fan_watchdog_store(struct device_driver *drv,
 	if (parse_strtoul(buf, 120, &t))
 		return -EINVAL;
 
+	if (!fan_control_allowed)
+		return -EPERM;
+
 	fan_watchdog_maxinterval = t;
 	fan_watchdog_reset();
 
@@ -3046,6 +3049,14 @@ static int __init fan_init(struct ibm_init_struct *iibm)
 		  fan_control_access_mode != TPACPI_FAN_WR_NONE),
 		fan_status_access_mode, fan_control_access_mode);
 
+	/* fan control master switch */
+	if (!fan_control_allowed) {
+		fan_control_access_mode = TPACPI_FAN_WR_NONE;
+		fan_control_commands = 0;
+		dbg_printk(TPACPI_DBG_INIT,
+			   "fan control features disabled by parameter\n");
+	}
+
 	/* update fan_control_desired_level */
 	if (fan_status_access_mode != TPACPI_FAN_NONE)
 		fan_get_status_safe(NULL);
@@ -3203,6 +3214,9 @@ static void fan_watchdog_reset(void)
 
 static int fan_set_level(int level)
 {
+	if (!fan_control_allowed)
+		return -EPERM;
+
 	switch (fan_control_access_mode) {
 	case TPACPI_FAN_WR_ACPI_SFAN:
 		if (level >= 0 && level <= 7) {
@@ -3242,6 +3256,9 @@ static int fan_set_level_safe(int level)
 {
 	int rc;
 
+	if (!fan_control_allowed)
+		return -EPERM;
+
 	rc = mutex_lock_interruptible(&fan_mutex);
 	if (rc < 0)
 		return rc;
@@ -3262,6 +3279,9 @@ static int fan_set_enable(void)
 	u8 s;
 	int rc;
 
+	if (!fan_control_allowed)
+		return -EPERM;
+
 	rc = mutex_lock_interruptible(&fan_mutex);
 	if (rc < 0)
 		return rc;
@@ -3315,6 +3335,9 @@ static int fan_set_disable(void)
 {
 	int rc;
 
+	if (!fan_control_allowed)
+		return -EPERM;
+
 	rc = mutex_lock_interruptible(&fan_mutex);
 	if (rc < 0)
 		return rc;
@@ -3351,6 +3374,9 @@ static int fan_set_speed(int speed)
 {
 	int rc;
 
+	if (!fan_control_allowed)
+		return -EPERM;
+
 	rc = mutex_lock_interruptible(&fan_mutex);
 	if (rc < 0)
 		return rc;
@@ -3558,7 +3584,6 @@ static struct ibm_struct fan_driver_data = {
 	.read = fan_read,
 	.write = fan_write,
 	.exit = fan_exit,
-	.flags.experimental = 1,
 };
 
 /****************************************************************************
@@ -3879,6 +3904,9 @@ module_param_named(debug, dbg_level, uint, 0);
 static int force_load;
 module_param(force_load, int, 0);
 
+static int fan_control_allowed;
+module_param_named(fan_control, fan_control_allowed, int, 0);
+
 #define IBM_PARAM(feature) \
 	module_param_call(feature, set_ibm_param, NULL, NULL, 0)
 
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 8348fc6..a9e7093 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -375,6 +375,8 @@ enum fan_control_commands {
 						 * and also watchdog cmd */
 };
 
+static int fan_control_allowed;
+
 static enum fan_status_access_mode fan_status_access_mode;
 static enum fan_control_access_mode fan_control_access_mode;
 static enum fan_control_commands fan_control_commands;
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 087/105] ACPI: thinkpad-acpi: do not arm fan watchdog if it would not work
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Do not enable/rearm the fan control safety watchdog if we would not be able
to do anything to the fan anyway.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 7dc3a22..f824259 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -3197,6 +3197,9 @@ static void fan_watchdog_reset(void)
 {
 	static int fan_watchdog_active = 0;
 
+	if (fan_control_access_mode == TPACPI_FAN_WR_NONE)
+		return;
+
 	if (fan_watchdog_active)
 		cancel_delayed_work(&fan_watchdog_task);
 
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 088/105] ACPI: thinkpad-acpi: fix a fan watchdog invocation
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

The fan control watchdog was being called in one place even when the fan
control operation had failed.  Fix it.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index f824259..b85f096 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -2888,9 +2888,10 @@ static ssize_t fan_pwm1_store(struct device *dev,
 	if (!rc && (status &
 		    (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) {
 		rc = fan_set_level(newlevel);
-		if (!rc)
+		if (!rc) {
 			fan_update_desired_level(newlevel);
-		fan_watchdog_reset();
+			fan_watchdog_reset();
+		}
 	}
 
 	mutex_unlock(&fan_mutex);
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 089/105] ACPI: thinkpad-acpi: map ENXIO to EINVAL for fan sysfs
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Currently, all fan control operations return ENXIO if unsupported
operations are requested, but return EINVAL if invalid fan modes are
requested on a given ThinkPad.

This is not strictly correct for sysfs, so map ENXIO to EINVAL in the sysfs
attribute store handlers, as we do benefit from the ENXIO in other parts of
the driver code.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index b85f096..7aed118 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -2824,7 +2824,9 @@ static ssize_t fan_pwm1_enable_store(struct device *dev,
 	}
 
 	res = fan_set_level_safe(level);
-	if (res < 0)
+	if (res == -ENXIO)
+		return -EINVAL;
+	else if (res < 0)
 		return res;
 
 	fan_watchdog_reset();
@@ -2888,7 +2890,9 @@ static ssize_t fan_pwm1_store(struct device *dev,
 	if (!rc && (status &
 		    (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) {
 		rc = fan_set_level(newlevel);
-		if (!rc) {
+		if (rc == -ENXIO)
+			rc = -EINVAL;
+		else if (!rc) {
 			fan_update_desired_level(newlevel);
 			fan_watchdog_reset();
 		}
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 090/105] ACPI: thinkpad-acpi: improve fan control documentation
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Improve fan control documentation and fix one mistake.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 Documentation/thinkpad-acpi.txt |   18 +++++++++++++-----
 1 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt
index bca50d7..e3ad7a4 100644
--- a/Documentation/thinkpad-acpi.txt
+++ b/Documentation/thinkpad-acpi.txt
@@ -795,15 +795,23 @@ Sysfs notes:
 The sysfs interface follows the hwmon subsystem guidelines for the most
 part, and the exception is the fan safety watchdog.
 
+Writes to any of the sysfs attributes may return the EINVAL error if
+that operation is not supported in a given ThinkPad or if the parameter
+is out-of-bounds, and EPERM if it is forbidden.  They may also return
+EINTR (interrupted system call), and EIO (I/O error while trying to talk
+to the firmware).
+
+Features not yet implemented by the driver return ENOSYS.
+
 hwmon device attribute pwm1_enable:
 	0: PWM offline (fan is set to full-speed mode)
 	1: Manual PWM control (use pwm1 to set fan level)
 	2: Hardware PWM control (EC "auto" mode)
 	3: reserved (Software PWM control, not implemented yet)
 
-	Modes 0 and 2 are not supported by all ThinkPads, and the driver
-	is not always able to detect this.  If it does know a mode is
-	unsupported, it will return -EINVAL.
+	Modes 0 and 2 are not supported by all ThinkPads, and the
+	driver is not always able to detect this.  If it does know a
+	mode is unsupported, it will return -EINVAL.
 
 hwmon device attribute pwm1:
 	Fan level, scaled from the firmware values of 0-7 to the hwmon
@@ -826,8 +834,8 @@ driver attribute fan_watchdog:
 To stop the fan: set pwm1 to zero, and pwm1_enable to 1.
 
 To start the fan in a safe mode: set pwm1_enable to 2.  If that fails
-with ENOTSUP, set it to 1 and set pwm1 to at least 128 (255 would be the
-safest choice, though).
+with EINVAL, try to set pwm1_enable to 1 and pwm1 to at least 128 (255
+would be the safest choice, though).
 
 
 EXPERIMENTAL: WAN -- /proc/acpi/ibm/wan
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 091/105] ACPI: thinkpad-acpi: improve debugging for acpi helpers
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Some issues with the dock subdriver proved that a slightly improved
debugging setup for ACPI notifiers and handler helpers would be useful.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |   31 ++++++++++++++++++++-----------
 1 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 7aed118..68f1cc0 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -296,14 +296,22 @@ static void drv_acpi_handle_init(char *name,
 	int i;
 	acpi_status status;
 
+	vdbg_printk(TPACPI_DBG_INIT, "trying to locate ACPI handle for %s\n",
+		name);
+
 	for (i = 0; i < num_paths; i++) {
 		status = acpi_get_handle(parent, paths[i], handle);
 		if (ACPI_SUCCESS(status)) {
 			*path = paths[i];
+			dbg_printk(TPACPI_DBG_INIT,
+				   "Found ACPI handle %s for %s\n",
+				   *path, name);
 			return;
 		}
 	}
 
+	vdbg_printk(TPACPI_DBG_INIT, "ACPI handle for %s not found\n",
+		    name);
 	*handle = NULL;
 }
 
@@ -320,19 +328,20 @@ static void dispatch_acpi_notify(acpi_handle handle, u32 event, void *data)
 static int __init setup_acpi_notify(struct ibm_struct *ibm)
 {
 	acpi_status status;
-	int ret;
+	int rc;
 
 	BUG_ON(!ibm->acpi);
 
 	if (!*ibm->acpi->handle)
 		return 0;
 
-	dbg_printk(TPACPI_DBG_INIT,
+	vdbg_printk(TPACPI_DBG_INIT,
 		"setting up ACPI notify for %s\n", ibm->name);
 
-	ret = acpi_bus_get_device(*ibm->acpi->handle, &ibm->acpi->device);
-	if (ret < 0) {
-		printk(IBM_ERR "%s device not present\n", ibm->name);
+	rc = acpi_bus_get_device(*ibm->acpi->handle, &ibm->acpi->device);
+	if (rc < 0) {
+		printk(IBM_ERR "acpi_bus_get_device(%s) failed: %d\n",
+			ibm->name, rc);
 		return -ENODEV;
 	}
 
@@ -364,7 +373,7 @@ static int __init tpacpi_device_add(struct acpi_device *device)
 
 static int __init register_tpacpi_subdriver(struct ibm_struct *ibm)
 {
-	int ret;
+	int rc;
 
 	dbg_printk(TPACPI_DBG_INIT,
 		"registering %s as an ACPI driver\n", ibm->name);
@@ -381,16 +390,16 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm)
 	ibm->acpi->driver->ids = ibm->acpi->hid;
 	ibm->acpi->driver->ops.add = &tpacpi_device_add;
 
-	ret = acpi_bus_register_driver(ibm->acpi->driver);
-	if (ret < 0) {
+	rc = acpi_bus_register_driver(ibm->acpi->driver);
+	if (rc < 0) {
 		printk(IBM_ERR "acpi_bus_register_driver(%s) failed: %d\n",
-		       ibm->acpi->hid, ret);
+		       ibm->acpi->hid, rc);
 		kfree(ibm->acpi->driver);
 		ibm->acpi->driver = NULL;
-	} else if (!ret)
+	} else if (!rc)
 		ibm->flags.acpi_driver_registered = 1;
 
-	return ret;
+	return rc;
 }
 
 
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 092/105] ACPI: thinkpad-acpi: improve dock subdriver initialization
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

The dock sub-driver has split-personality (two subdrivers), and it was
doing some unoptimal things on init because of that.  Fix it so that the
second half of it will only init when necessary, and only if the first half
initialized sucessfully in the first place.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.c |   78 +++++++++++++++++++++++++++---------------
 1 files changed, 50 insertions(+), 28 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 68f1cc0..a565265 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -1519,6 +1519,33 @@ IBM_HANDLE(dock, root, "\\_SB.GDCK",	/* X30, X31, X40 */
 /* don't list other alternatives as we install a notify handler on the 570 */
 IBM_HANDLE(pci, root, "\\_SB.PCI");	/* 570 */
 
+static struct tp_acpi_drv_struct ibm_dock_acpidriver[2] = {
+	{
+	 .notify = dock_notify,
+	 .handle = &dock_handle,
+	 .type = ACPI_SYSTEM_NOTIFY,
+	},
+	{
+	 .hid = IBM_PCI_HID,
+	 .notify = dock_notify,
+	 .handle = &pci_handle,
+	 .type = ACPI_SYSTEM_NOTIFY,
+	},
+};
+
+static struct ibm_struct dock_driver_data[2] = {
+	{
+	 .name = "dock",
+	 .read = dock_read,
+	 .write = dock_write,
+	 .acpi = &ibm_dock_acpidriver[0],
+	},
+	{
+	 .name = "dock",
+	 .acpi = &ibm_dock_acpidriver[1],
+	},
+};
+
 #define dock_docked() (_sta(dock_handle) & 1)
 
 static int __init dock_init(struct ibm_init_struct *iibm)
@@ -1526,7 +1553,6 @@ static int __init dock_init(struct ibm_init_struct *iibm)
 	vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver\n");
 
 	IBM_ACPIHANDLE_INIT(dock);
-	IBM_ACPIHANDLE_INIT(pci);
 
 	vdbg_printk(TPACPI_DBG_INIT, "dock is %s\n",
 		str_supported(dock_handle != NULL));
@@ -1534,6 +1560,28 @@ static int __init dock_init(struct ibm_init_struct *iibm)
 	return (dock_handle)? 0 : 1;
 }
 
+static int __init dock_init2(struct ibm_init_struct *iibm)
+{
+	int dock2_needed;
+
+	vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver part 2\n");
+
+	if (dock_driver_data[0].flags.acpi_driver_registered &&
+	    dock_driver_data[0].flags.acpi_notify_installed) {
+		IBM_ACPIHANDLE_INIT(pci);
+		dock2_needed = (pci_handle != NULL);
+		vdbg_printk(TPACPI_DBG_INIT,
+			    "dock PCI handler for the TP 570 is %s\n",
+			    str_supported(dock2_needed));
+	} else {
+		vdbg_printk(TPACPI_DBG_INIT,
+		"dock subdriver part 2 not required\n");
+		dock2_needed = 0;
+	}
+
+	return (dock2_needed)? 0 : 1;
+}
+
 static void dock_notify(struct ibm_struct *ibm, u32 event)
 {
 	int docked = dock_docked();
@@ -1595,33 +1643,6 @@ static int dock_write(char *buf)
 	return 0;
 }
 
-static struct tp_acpi_drv_struct ibm_dock_acpidriver[2] = {
-	{
-	 .notify = dock_notify,
-	 .handle = &dock_handle,
-	 .type = ACPI_SYSTEM_NOTIFY,
-	},
-	{
-	 .hid = IBM_PCI_HID,
-	 .notify = dock_notify,
-	 .handle = &pci_handle,
-	 .type = ACPI_SYSTEM_NOTIFY,
-	},
-};
-
-static struct ibm_struct dock_driver_data[2] = {
-	{
-	 .name = "dock",
-	 .read = dock_read,
-	 .write = dock_write,
-	 .acpi = &ibm_dock_acpidriver[0],
-	},
-	{
-	 .name = "dock",
-	 .acpi = &ibm_dock_acpidriver[1],
-	},
-};
-
 #endif /* CONFIG_THINKPAD_ACPI_DOCK */
 
 /*************************************************************************
@@ -3850,6 +3871,7 @@ static struct ibm_init_struct ibms_init[] __initdata = {
 		.data = &dock_driver_data[0],
 	},
 	{
+		.init = dock_init2,
 		.data = &dock_driver_data[1],
 	},
 #endif
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 093/105] ACPI: thinkpad-acpi: add sysfs support to hotkey subdriver
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Add the hotkey sysfs support.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 Documentation/thinkpad-acpi.txt |   58 ++++++++++++++----
 drivers/misc/thinkpad_acpi.c    |  127 +++++++++++++++++++++++++++++++++++++++
 drivers/misc/thinkpad_acpi.h    |    2 +
 3 files changed, 176 insertions(+), 11 deletions(-)

diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt
index e3ad7a4..ebeed58 100644
--- a/Documentation/thinkpad-acpi.txt
+++ b/Documentation/thinkpad-acpi.txt
@@ -134,8 +134,11 @@ end of this document.  Changes to the sysfs interface done by the kernel
 subsystems are not documented here, nor are they tracked by this
 attribute.
 
-Hot keys -- /proc/acpi/ibm/hotkey
----------------------------------
+Hot keys
+--------
+
+procfs: /proc/acpi/ibm/hotkey
+sysfs device attribute: hotkey/*
 
 Without this driver, only the Fn-F4 key (sleep button) generates an
 ACPI event. With the driver loaded, the hotkey feature enabled and the
@@ -149,15 +152,6 @@ All labeled Fn-Fx key combinations generate distinct events. In
 addition, the lid microswitch and some docking station buttons may
 also generate such events.
 
-The following commands can be written to this file:
-
-	echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature
-	echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature
-	echo 0xffff > /proc/acpi/ibm/hotkey -- enable all possible hot keys
-	echo 0x0000 > /proc/acpi/ibm/hotkey -- disable all possible hot keys
-	... any other 4-hex-digit mask ...
-	echo reset > /proc/acpi/ibm/hotkey -- restore the original mask
-
 The bit mask allows some control over which hot keys generate ACPI
 events. Not all bits in the mask can be modified. Not all bits that
 can be modified do anything. Not all hot keys can be individually
@@ -189,6 +183,48 @@ buttons do not generate ACPI events even with this driver. They *can*
 be used through the "ThinkPad Buttons" utility, see
 http://www.nongnu.org/tpb/
 
+procfs notes:
+
+The following commands can be written to the /proc/acpi/ibm/hotkey file:
+
+	echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature
+	echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature
+	echo 0xffff > /proc/acpi/ibm/hotkey -- enable all possible hot keys
+	echo 0x0000 > /proc/acpi/ibm/hotkey -- disable all possible hot keys
+	... any other 4-hex-digit mask ...
+	echo reset > /proc/acpi/ibm/hotkey -- restore the original mask
+
+sysfs notes:
+
+	The hot keys attributes are in a hotkey/ subdirectory off the
+	thinkpad device.
+
+	bios_enabled:
+		Returns the status of the hot keys feature when
+		thinkpad-acpi was loaded.  Upon module unload, the hot
+		key feature status will be restored to this value.
+
+		0: hot keys were disabled
+		1: hot keys were enabled
+
+	bios_mask:
+		Returns the hot keys mask when thinkpad-acpi was loaded.
+		Upon module unload, the hot keys mask will be restored
+		to this value.
+
+	enable:
+		Enables/disables the hot keys feature, and reports
+		current status of the hot keys feature.
+
+		0: disables the hot keys feature / feature disabled
+		1: enables the hot keys feature / feature enabled
+
+	mask:
+		bit mask to enable ACPI event generation for each hot
+		key (see above).  Returns the current status of the hot
+		keys mask, and allows one to modify it.
+
+
 Bluetooth -- /proc/acpi/ibm/bluetooth
 -------------------------------------
 
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index a565265..83a8d98 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -706,6 +706,108 @@ static struct ibm_struct thinkpad_acpi_driver_data = {
 static int hotkey_orig_status;
 static int hotkey_orig_mask;
 
+static struct attribute_set *hotkey_dev_attributes = NULL;
+
+/* sysfs hotkey enable ------------------------------------------------- */
+static ssize_t hotkey_enable_show(struct device *dev,
+			   struct device_attribute *attr,
+			   char *buf)
+{
+	int res, status, mask;
+
+	res = hotkey_get(&status, &mask);
+	if (res)
+		return res;
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", status);
+}
+
+static ssize_t hotkey_enable_store(struct device *dev,
+			    struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	unsigned long t;
+	int res, status, mask;
+
+	if (parse_strtoul(buf, 1, &t))
+		return -EINVAL;
+
+	res = hotkey_get(&status, &mask);
+	if (!res)
+		res = hotkey_set(t, mask);
+
+	return (res) ? res : count;
+}
+
+static struct device_attribute dev_attr_hotkey_enable =
+	__ATTR(enable, S_IWUSR | S_IRUGO,
+		hotkey_enable_show, hotkey_enable_store);
+
+/* sysfs hotkey mask --------------------------------------------------- */
+static ssize_t hotkey_mask_show(struct device *dev,
+			   struct device_attribute *attr,
+			   char *buf)
+{
+	int res, status, mask;
+
+	res = hotkey_get(&status, &mask);
+	if (res)
+		return res;
+
+	return snprintf(buf, PAGE_SIZE, "0x%04x\n", mask);
+}
+
+static ssize_t hotkey_mask_store(struct device *dev,
+			    struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	unsigned long t;
+	int res, status, mask;
+
+	if (parse_strtoul(buf, 0xffff, &t))
+		return -EINVAL;
+
+	res = hotkey_get(&status, &mask);
+	if (!res)
+		hotkey_set(status, t);
+
+	return (res) ? res : count;
+}
+
+static struct device_attribute dev_attr_hotkey_mask =
+	__ATTR(mask, S_IWUSR | S_IRUGO,
+		hotkey_mask_show, hotkey_mask_store);
+
+/* sysfs hotkey bios_enabled ------------------------------------------- */
+static ssize_t hotkey_bios_enabled_show(struct device *dev,
+			   struct device_attribute *attr,
+			   char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_orig_status);
+}
+
+static struct device_attribute dev_attr_hotkey_bios_enabled =
+	__ATTR(bios_enabled, S_IRUGO, hotkey_bios_enabled_show, NULL);
+
+/* sysfs hotkey bios_mask ---------------------------------------------- */
+static ssize_t hotkey_bios_mask_show(struct device *dev,
+			   struct device_attribute *attr,
+			   char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "0x%04x\n", hotkey_orig_mask);
+}
+
+static struct device_attribute dev_attr_hotkey_bios_mask =
+	__ATTR(bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL);
+
+/* --------------------------------------------------------------------- */
+
+static struct attribute *hotkey_mask_attributes[] = {
+	&dev_attr_hotkey_mask.attr,
+	&dev_attr_hotkey_bios_enabled.attr,
+	&dev_attr_hotkey_bios_mask.attr,
+};
+
 static int __init hotkey_init(struct ibm_init_struct *iibm)
 {
 	int res;
@@ -722,6 +824,15 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
 		str_supported(tp_features.hotkey));
 
 	if (tp_features.hotkey) {
+		hotkey_dev_attributes = create_attr_set(4,
+						TPACPI_HOTKEY_SYSFS_GROUP);
+		if (!hotkey_dev_attributes)
+			return -ENOMEM;
+		res = add_to_attr_set(hotkey_dev_attributes,
+				&dev_attr_hotkey_enable.attr);
+		if (res)
+			return res;
+
 		/* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
 		   A30, R30, R31, T20-22, X20-21, X22-24 */
 		tp_features.hotkey_mask =
@@ -731,6 +842,16 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
 			str_supported(tp_features.hotkey_mask));
 
 		res = hotkey_get(&hotkey_orig_status, &hotkey_orig_mask);
+		if (!res && tp_features.hotkey_mask) {
+			res = add_many_to_attr_set(hotkey_dev_attributes,
+				hotkey_mask_attributes,
+				ARRAY_SIZE(hotkey_mask_attributes));
+		}
+		if (!res)
+			res = register_attr_set_with_sysfs(
+					hotkey_dev_attributes,
+					&tpacpi_pdev->dev.kobj);
+
 		if (res)
 			return res;
 	}
@@ -748,6 +869,11 @@ static void hotkey_exit(void)
 		if (res)
 			printk(IBM_ERR "failed to restore hotkey to BIOS defaults\n");
 	}
+
+	if (hotkey_dev_attributes) {
+		delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj);
+		hotkey_dev_attributes = NULL;
+	}
 }
 
 static void hotkey_notify(struct ibm_struct *ibm, u32 event)
@@ -798,6 +924,7 @@ static int hotkey_set(int status, int mask)
 	return 0;
 }
 
+/* procfs -------------------------------------------------------------- */
 static int hotkey_read(char *p)
 {
 	int res, status, mask;
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index a9e7093..7615adb 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -414,6 +414,8 @@ static int fan_write_cmd_watchdog(const char *cmd, int *rc);
  * Hotkey subdriver
  */
 
+#define TPACPI_HOTKEY_SYSFS_GROUP "hotkey"
+
 static int hotkey_orig_status;
 static int hotkey_orig_mask;
 
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 094/105] ACPI: thinkpad-acpi: add sysfs support to wan and bluetooth subdrivers
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Henrique de Moraes Holschuh, Len Brown

From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

Add support to sysfs to the wan and bluetooth subdrivers.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 Documentation/thinkpad-acpi.txt |   61 ++++++++++++++---
 drivers/misc/thinkpad_acpi.c    |  144 +++++++++++++++++++++++++++++++++++---
 drivers/misc/thinkpad_acpi.h    |    4 +
 3 files changed, 186 insertions(+), 23 deletions(-)

diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt
index ebeed58..2d48033 100644
--- a/Documentation/thinkpad-acpi.txt
+++ b/Documentation/thinkpad-acpi.txt
@@ -225,15 +225,35 @@ sysfs notes:
 		keys mask, and allows one to modify it.
 
 
-Bluetooth -- /proc/acpi/ibm/bluetooth
--------------------------------------
+Bluetooth
+---------
 
-This feature shows the presence and current state of a Bluetooth
-device. If Bluetooth is installed, the following commands can be used:
+procfs: /proc/acpi/ibm/bluetooth
+sysfs device attribute: bluetooth/enable
+
+This feature shows the presence and current state of a ThinkPad
+Bluetooth device in the internal ThinkPad CDC slot.
+
+Procfs notes:
+
+If Bluetooth is installed, the following commands can be used:
 
 	echo enable > /proc/acpi/ibm/bluetooth
 	echo disable > /proc/acpi/ibm/bluetooth
 
+Sysfs notes:
+
+	If the Bluetooth CDC card is installed, it can be enabled /
+	disabled through the "bluetooth/enable" thinkpad-acpi device
+	attribute, and its current status can also be queried.
+
+	enable:
+		0: disables Bluetooth / Bluetooth is disabled
+		1: enables Bluetooth / Bluetooth is enabled.
+
+	Note: this interface will be probably be superseeded by the
+	generic rfkill class.
+
 Video output control -- /proc/acpi/ibm/video
 --------------------------------------------
 
@@ -874,23 +894,42 @@ with EINVAL, try to set pwm1_enable to 1 and pwm1 to at least 128 (255
 would be the safest choice, though).
 
 
-EXPERIMENTAL: WAN -- /proc/acpi/ibm/wan
----------------------------------------
+EXPERIMENTAL: WAN
+-----------------
+
+procfs: /proc/acpi/ibm/wan
+sysfs device attribute: wwan/enable
 
 This feature is marked EXPERIMENTAL because the implementation
 directly accesses hardware registers and may not work as expected. USE
 WITH CAUTION! To use this feature, you need to supply the
 experimental=1 parameter when loading the module.
 
-This feature shows the presence and current state of a WAN (Sierra
-Wireless EV-DO) device. If WAN is installed, the following commands can
-be used:
+This feature shows the presence and current state of a W-WAN (Sierra
+Wireless EV-DO) device.
+
+It was tested on a Lenovo Thinkpad X60. It should probably work on other
+Thinkpad models which come with this module installed.
+
+Procfs notes:
+
+If the W-WAN card is installed, the following commands can be used:
 
 	echo enable > /proc/acpi/ibm/wan
 	echo disable > /proc/acpi/ibm/wan
 
-It was tested on a Lenovo Thinkpad X60. It should probably work on other
-Thinkpad models which come with this module installed.
+Sysfs notes:
+
+	If the W-WAN card is installed, it can be enabled /
+	disabled through the "wwan/enable" thinkpad-acpi device
+	attribute, and its current status can also be queried.
+
+	enable:
+		0: disables WWAN card / WWAN card is disabled
+		1: enables WWAN card / WWAN card is enabled.
+
+	Note: this interface will be probably be superseeded by the
+	generic rfkill class.
 
 Multiple Commands, Module Parameters
 ------------------------------------
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 83a8d98..6c36a55 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -1020,8 +1020,54 @@ static struct ibm_struct hotkey_driver_data = {
  * Bluetooth subdriver
  */
 
+/* sysfs bluetooth enable ---------------------------------------------- */
+static ssize_t bluetooth_enable_show(struct device *dev,
+			   struct device_attribute *attr,
+			   char *buf)
+{
+	int status;
+
+	status = bluetooth_get_radiosw();
+	if (status < 0)
+		return status;
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", status ? 1 : 0);
+}
+
+static ssize_t bluetooth_enable_store(struct device *dev,
+			    struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	unsigned long t;
+	int res;
+
+	if (parse_strtoul(buf, 1, &t))
+		return -EINVAL;
+
+	res = bluetooth_set_radiosw(t);
+
+	return (res) ? res : count;
+}
+
+static struct device_attribute dev_attr_bluetooth_enable =
+	__ATTR(enable, S_IWUSR | S_IRUGO,
+		bluetooth_enable_show, bluetooth_enable_store);
+
+/* --------------------------------------------------------------------- */
+
+static struct attribute *bluetooth_attributes[] = {
+	&dev_attr_bluetooth_enable.attr,
+	NULL
+};
+
+static const struct attribute_group bluetooth_attr_group = {
+	.name = TPACPI_BLUETH_SYSFS_GROUP,
+	.attrs = bluetooth_attributes,
+};
+
 static int __init bluetooth_init(struct ibm_init_struct *iibm)
 {
+	int res;
 	int status = 0;
 
 	vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n");
@@ -1037,17 +1083,29 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
 		str_supported(tp_features.bluetooth),
 		status);
 
-	if (tp_features.bluetooth &&
-	    !(status & TP_ACPI_BLUETOOTH_HWPRESENT)) {
-		/* no bluetooth hardware present in system */
-		tp_features.bluetooth = 0;
-		dbg_printk(TPACPI_DBG_INIT,
-			   "bluetooth hardware not installed\n");
+	if (tp_features.bluetooth) {
+		if (!(status & TP_ACPI_BLUETOOTH_HWPRESENT)) {
+			/* no bluetooth hardware present in system */
+			tp_features.bluetooth = 0;
+			dbg_printk(TPACPI_DBG_INIT,
+				   "bluetooth hardware not installed\n");
+		} else {
+			res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
+					&bluetooth_attr_group);
+			if (res)
+				return res;
+		}
 	}
 
 	return (tp_features.bluetooth)? 0 : 1;
 }
 
+static void bluetooth_exit(void)
+{
+	sysfs_remove_group(&tpacpi_pdev->dev.kobj,
+			&bluetooth_attr_group);
+}
+
 static int bluetooth_get_radiosw(void)
 {
 	int status;
@@ -1080,6 +1138,7 @@ static int bluetooth_set_radiosw(int radio_on)
 	return 0;
 }
 
+/* procfs -------------------------------------------------------------- */
 static int bluetooth_read(char *p)
 {
 	int len = 0;
@@ -1119,14 +1178,61 @@ static struct ibm_struct bluetooth_driver_data = {
 	.name = "bluetooth",
 	.read = bluetooth_read,
 	.write = bluetooth_write,
+	.exit = bluetooth_exit,
 };
 
 /*************************************************************************
  * Wan subdriver
  */
 
+/* sysfs wan enable ---------------------------------------------------- */
+static ssize_t wan_enable_show(struct device *dev,
+			   struct device_attribute *attr,
+			   char *buf)
+{
+	int status;
+
+	status = wan_get_radiosw();
+	if (status < 0)
+		return status;
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", status ? 1 : 0);
+}
+
+static ssize_t wan_enable_store(struct device *dev,
+			    struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	unsigned long t;
+	int res;
+
+	if (parse_strtoul(buf, 1, &t))
+		return -EINVAL;
+
+	res = wan_set_radiosw(t);
+
+	return (res) ? res : count;
+}
+
+static struct device_attribute dev_attr_wan_enable =
+	__ATTR(enable, S_IWUSR | S_IRUGO,
+		wan_enable_show, wan_enable_store);
+
+/* --------------------------------------------------------------------- */
+
+static struct attribute *wan_attributes[] = {
+	&dev_attr_wan_enable.attr,
+	NULL
+};
+
+static const struct attribute_group wan_attr_group = {
+	.name = TPACPI_WAN_SYSFS_GROUP,
+	.attrs = wan_attributes,
+};
+
 static int __init wan_init(struct ibm_init_struct *iibm)
 {
+	int res;
 	int status = 0;
 
 	vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n");
@@ -1140,17 +1246,29 @@ static int __init wan_init(struct ibm_init_struct *iibm)
 		str_supported(tp_features.wan),
 		status);
 
-	if (tp_features.wan &&
-	    !(status & TP_ACPI_WANCARD_HWPRESENT)) {
-		/* no wan hardware present in system */
-		tp_features.wan = 0;
-		dbg_printk(TPACPI_DBG_INIT,
-			   "wan hardware not installed\n");
+	if (tp_features.wan) {
+		if (!(status & TP_ACPI_WANCARD_HWPRESENT)) {
+			/* no wan hardware present in system */
+			tp_features.wan = 0;
+			dbg_printk(TPACPI_DBG_INIT,
+				   "wan hardware not installed\n");
+		} else {
+			res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
+					&wan_attr_group);
+			if (res)
+				return res;
+		}
 	}
 
 	return (tp_features.wan)? 0 : 1;
 }
 
+static void wan_exit(void)
+{
+	sysfs_remove_group(&tpacpi_pdev->dev.kobj,
+		&wan_attr_group);
+}
+
 static int wan_get_radiosw(void)
 {
 	int status;
@@ -1183,6 +1301,7 @@ static int wan_set_radiosw(int radio_on)
 	return 0;
 }
 
+/* procfs -------------------------------------------------------------- */
 static int wan_read(char *p)
 {
 	int len = 0;
@@ -1222,6 +1341,7 @@ static struct ibm_struct wan_driver_data = {
 	.name = "wan",
 	.read = wan_read,
 	.write = wan_write,
+	.exit = wan_exit,
 	.flags.experimental = 1,
 };
 
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 7615adb..a6c2855 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -278,6 +278,8 @@ static int beep_write(char *buf);
  * Bluetooth subdriver
  */
 
+#define TPACPI_BLUETH_SYSFS_GROUP "bluetooth"
+
 enum {
 	/* ACPI GBDC/SBDC bits */
 	TP_ACPI_BLUETOOTH_HWPRESENT	= 0x01,	/* Bluetooth hw available */
@@ -551,6 +553,8 @@ static int volume_write(char *buf);
  * Wan subdriver
  */
 
+#define TPACPI_WAN_SYSFS_GROUP "wwan"
+
 enum {
 	/* ACPI GWAN/SWAN bits */
 	TP_ACPI_WANCARD_HWPRESENT	= 0x01,	/* Wan hw available */
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 095/105] thinkpad-acpi: make drivers/misc/thinkpad_acpi:fan_mutex static
@ 2007-04-29  4:51       ` Len Brown
       [not found]         ` <11778223931192-git-send-email-len.brown@intel.com>
  0 siblings, 1 reply; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Adrian Bunk, Len Brown

From: Adrian Bunk <bunk@stusta.de>

This patch makes the needlessly global fan_mutex static.

Signed-off-by: Adrian Bunk <bunk@stusta.de>
Acked-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/misc/thinkpad_acpi.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index a6c2855..440145a 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -386,7 +386,7 @@ static u8 fan_control_initial_status;
 static u8 fan_control_desired_level;
 static int fan_watchdog_maxinterval;
 
-struct mutex fan_mutex;
+static struct mutex fan_mutex;
 
 static acpi_handle fans_handle, gfan_handle, sfan_handle;
 
-- 
1.5.2.rc0.34.gda94

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

* [PATCH 105/105] sonypi: use mutex instead of semaphore
@ 2007-04-29  4:51       ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-04-29  4:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Matthias Kaehlcke, Len Brown

From: Matthias Kaehlcke <matthias.kaehlcke@gmail.com>

the Sony Programmable I/O Control driver uses a semaphore as
mutex. use the mutex API instead of the (binary) semaphore

Signed-off-by: Matthias Kaehlcke <matthias.kaehlcke@gmail.com>
Acked-by: Mattia Dongili <malattia@linux.it>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/char/sonypi.c |   20 ++++++++++----------
 1 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index b699890..3ef593a 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -484,7 +484,7 @@ static struct sonypi_device {
 	u16 evtype_offset;
 	int camera_power;
 	int bluetooth_power;
-	struct semaphore lock;
+	struct mutex lock;
 	struct kfifo *fifo;
 	spinlock_t fifo_lock;
 	wait_queue_head_t fifo_proc_list;
@@ -891,7 +891,7 @@ int sonypi_camera_command(int command, u8 value)
 	if (!camera)
 		return -EIO;
 
-	down(&sonypi_device.lock);
+	mutex_lock(&sonypi_device.lock);
 
 	switch (command) {
 	case SONYPI_COMMAND_SETCAMERA:
@@ -926,7 +926,7 @@ int sonypi_camera_command(int command, u8 value)
 		       command);
 		break;
 	}
-	up(&sonypi_device.lock);
+	mutex_unlock(&sonypi_device.lock);
 	return 0;
 }
 
@@ -945,20 +945,20 @@ static int sonypi_misc_fasync(int fd, struct file *filp, int on)
 static int sonypi_misc_release(struct inode *inode, struct file *file)
 {
 	sonypi_misc_fasync(-1, file, 0);
-	down(&sonypi_device.lock);
+	mutex_lock(&sonypi_device.lock);
 	sonypi_device.open_count--;
-	up(&sonypi_device.lock);
+	mutex_unlock(&sonypi_device.lock);
 	return 0;
 }
 
 static int sonypi_misc_open(struct inode *inode, struct file *file)
 {
-	down(&sonypi_device.lock);
+	mutex_lock(&sonypi_device.lock);
 	/* Flush input queue on first open */
 	if (!sonypi_device.open_count)
 		kfifo_reset(sonypi_device.fifo);
 	sonypi_device.open_count++;
-	up(&sonypi_device.lock);
+	mutex_unlock(&sonypi_device.lock);
 	return 0;
 }
 
@@ -1008,7 +1008,7 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
 	u8 val8;
 	u16 val16;
 
-	down(&sonypi_device.lock);
+	mutex_lock(&sonypi_device.lock);
 	switch (cmd) {
 	case SONYPI_IOCGBRT:
 		if (sonypi_ec_read(SONYPI_LCD_LIGHT, &val8)) {
@@ -1108,7 +1108,7 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
 	default:
 		ret = -EINVAL;
 	}
-	up(&sonypi_device.lock);
+	mutex_unlock(&sonypi_device.lock);
 	return ret;
 }
 
@@ -1363,7 +1363,7 @@ static int __devinit sonypi_probe(struct platform_device *dev)
 	}
 
 	init_waitqueue_head(&sonypi_device.fifo_proc_list);
-	init_MUTEX(&sonypi_device.lock);
+	mutex_init(&sonypi_device.lock);
 	sonypi_device.bluetooth_power = -1;
 
 	if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
-- 
1.5.2.rc0.34.gda94

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

* Re: [PATCH 083/105] ACPI: prevent ACPI quirk warning mass spamming in logs
  2007-04-29  4:51       ` Len Brown
@ 2007-04-29  9:58         ` Andi Kleen
  0 siblings, 0 replies; 89+ messages in thread
From: Andi Kleen @ 2007-04-29  9:58 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi, Thierry Vignaud, Andrew Morton

On Sunday 29 April 2007 06:51:23 Len Brown wrote:
> From: Thierry Vignaud <tvignaud@mandriva.com>
> 
> The following patch prevent this warning to be displayed again & again (eg:
> nine times on my NForce2 motherboard) and thus improve signal to noise
> ratio in logs.

I already got that in my tree. Better let me submit it.

-Andi

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

* Re: [PATCH 084/105] ACPI: Remove a warning about unused variable in !CONFIG_ACPI compilation.
  2007-04-29  4:51       ` Len Brown
@ 2007-04-29  9:59         ` Andi Kleen
  0 siblings, 0 replies; 89+ messages in thread
From: Andi Kleen @ 2007-04-29  9:59 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi, Zachary Amsden, Andrew Morton

On Sunday 29 April 2007 06:51:24 Len Brown wrote:
> From: Zachary Amsden <zach@vmware.com>

Also got that one already

-Andi

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

* Re: ACPI patches for 2.6.22 merge window
  2007-04-29  4:50 ACPI patches for 2.6.22 merge window Len Brown
       [not found] ` <11778223068-git-send-email-len.brown@intel.com>
@ 2007-05-01  2:19 ` Mattia Dongili
  2007-05-10  6:44   ` Len Brown
  1 sibling, 1 reply; 89+ messages in thread
From: Mattia Dongili @ 2007-05-01  2:19 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi

On Sun, Apr 29, 2007 at 12:50:00AM -0400, Len Brown wrote:
...
> If I've missed something that you think is appropriate
> for 2.6.22 (I'm sure there are several) please let me know.

It's me who actually forgot to submit a trivial patch for 2.6.22,
appended below.

mattia
---
Subject: rename SONY_LAPTOP_OLD to a more meaningful SONYPI_COMPAT

Signed-off-by: Mattia Dongili <malattia@linux.it>
---
Index: linux-2.6/drivers/misc/Kconfig
===================================================================
--- linux-2.6.orig/drivers/misc/Kconfig	2007-04-30 12:18:58.534918327 +0900
+++ linux-2.6/drivers/misc/Kconfig	2007-04-30 12:19:24.036371572 +0900
@@ -121,7 +121,7 @@ config SONY_LAPTOP
 
 	  Read <file:Documentation/sony-laptop.txt> for more information.
 
-config SONY_LAPTOP_OLD
+config SONYPI_COMPAT
 	bool "Sonypi compatibility"
 	depends on SONY_LAPTOP
 	  ---help---
Index: linux-2.6/drivers/misc/sony-laptop.c
===================================================================
--- linux-2.6.orig/drivers/misc/sony-laptop.c	2007-04-30 12:18:55.534747357 +0900
+++ linux-2.6/drivers/misc/sony-laptop.c	2007-04-30 12:19:35.537026957 +0900
@@ -63,7 +63,7 @@
 #include <asm/uaccess.h>
 #include <linux/sonypi.h>
 #include <linux/sony-laptop.h>
-#ifdef CONFIG_SONY_LAPTOP_OLD
+#ifdef CONFIG_SONYPI_COMPAT
 #include <linux/poll.h>
 #include <linux/miscdevice.h>
 #endif
@@ -114,7 +114,7 @@ MODULE_PARM_DESC(camera,
 		 "set this to 1 to enable Motion Eye camera controls "
 		 "(only use it if you have a C1VE or C1VN model)");
 
-#ifdef CONFIG_SONY_LAPTOP_OLD
+#ifdef CONFIG_SONYPI_COMPAT
 static int minor = -1;
 module_param(minor, int, 0);
 MODULE_PARM_DESC(minor,
@@ -1504,7 +1504,7 @@ static struct attribute_group spic_attri
 };
 
 /******** SONYPI compatibility **********/
-#ifdef CONFIG_SONY_LAPTOP_OLD
+#ifdef CONFIG_SONYPI_COMPAT
 
 /* battery / brightness / temperature  addresses */
 #define SONYPI_BAT_FLAGS	0x81
@@ -1798,7 +1798,7 @@ static void sonypi_compat_exit(void)
 static int sonypi_compat_init(void) { return 0; }
 static void sonypi_compat_exit(void) { }
 static void sonypi_compat_report_event(u8 event) { }
-#endif /* CONFIG_SONY_LAPTOP_OLD */
+#endif /* CONFIG_SONYPI_COMPAT */
 
 /*
  * ACPI callbacks

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

* Re: ACPI patches for 2.6.22 merge window
  2007-05-01  2:19 ` ACPI patches for 2.6.22 merge window Mattia Dongili
@ 2007-05-10  6:44   ` Len Brown
  0 siblings, 0 replies; 89+ messages in thread
From: Len Brown @ 2007-05-10  6:44 UTC (permalink / raw)
  To: Mattia Dongili; +Cc: linux-acpi

Applied.

thanks,
-Len

On Monday 30 April 2007 22:19, Mattia Dongili wrote:
> On Sun, Apr 29, 2007 at 12:50:00AM -0400, Len Brown wrote:
> ...
> > If I've missed something that you think is appropriate
> > for 2.6.22 (I'm sure there are several) please let me know.
> 
> It's me who actually forgot to submit a trivial patch for 2.6.22,
> appended below.
> 
> mattia
> ---
> Subject: rename SONY_LAPTOP_OLD to a more meaningful SONYPI_COMPAT
> 
> Signed-off-by: Mattia Dongili <malattia@linux.it>
> ---
> Index: linux-2.6/drivers/misc/Kconfig
> ===================================================================
> --- linux-2.6.orig/drivers/misc/Kconfig	2007-04-30 12:18:58.534918327 +0900
> +++ linux-2.6/drivers/misc/Kconfig	2007-04-30 12:19:24.036371572 +0900
> @@ -121,7 +121,7 @@ config SONY_LAPTOP
>  
>  	  Read <file:Documentation/sony-laptop.txt> for more information.
>  
> -config SONY_LAPTOP_OLD
> +config SONYPI_COMPAT
>  	bool "Sonypi compatibility"
>  	depends on SONY_LAPTOP
>  	  ---help---
> Index: linux-2.6/drivers/misc/sony-laptop.c
> ===================================================================
> --- linux-2.6.orig/drivers/misc/sony-laptop.c	2007-04-30 12:18:55.534747357 +0900
> +++ linux-2.6/drivers/misc/sony-laptop.c	2007-04-30 12:19:35.537026957 +0900
> @@ -63,7 +63,7 @@
>  #include <asm/uaccess.h>
>  #include <linux/sonypi.h>
>  #include <linux/sony-laptop.h>
> -#ifdef CONFIG_SONY_LAPTOP_OLD
> +#ifdef CONFIG_SONYPI_COMPAT
>  #include <linux/poll.h>
>  #include <linux/miscdevice.h>
>  #endif
> @@ -114,7 +114,7 @@ MODULE_PARM_DESC(camera,
>  		 "set this to 1 to enable Motion Eye camera controls "
>  		 "(only use it if you have a C1VE or C1VN model)");
>  
> -#ifdef CONFIG_SONY_LAPTOP_OLD
> +#ifdef CONFIG_SONYPI_COMPAT
>  static int minor = -1;
>  module_param(minor, int, 0);
>  MODULE_PARM_DESC(minor,
> @@ -1504,7 +1504,7 @@ static struct attribute_group spic_attri
>  };
>  
>  /******** SONYPI compatibility **********/
> -#ifdef CONFIG_SONY_LAPTOP_OLD
> +#ifdef CONFIG_SONYPI_COMPAT
>  
>  /* battery / brightness / temperature  addresses */
>  #define SONYPI_BAT_FLAGS	0x81
> @@ -1798,7 +1798,7 @@ static void sonypi_compat_exit(void)
>  static int sonypi_compat_init(void) { return 0; }
>  static void sonypi_compat_exit(void) { }
>  static void sonypi_compat_report_event(u8 event) { }
> -#endif /* CONFIG_SONY_LAPTOP_OLD */
> +#endif /* CONFIG_SONYPI_COMPAT */
>  
>  /*
>   * ACPI callbacks
> -
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

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

end of thread, other threads:[~2007-05-10  6:45 UTC | newest]

Thread overview: 89+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-04-29  4:50 ACPI patches for 2.6.22 merge window Len Brown
     [not found] ` <11778223068-git-send-email-len.brown@intel.com>
     [not found]   ` <ac122bb64b0d51f0512185d3522a75f3f3a80bc9.1177822058.git.len.brown@intel.com>
2007-04-29  4:50     ` [PATCH 002/105] ACPI: EC: Don't use Global Lock if not asked to do so Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 003/105] ACPI: EC: Make EC to initialize first in ACPI Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 004/105] ACPI: EC: "Fake ECDT" workaround is not needed any longer Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 005/105] ACPI: EC: enable burst functionality in EC Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 006/105] ACPI: EC: Remove casts to/from void* from ec.c Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 007/105] ACPI: EC: Put install handlers into separate function Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 008/105] ACPI: EC: Clean ECDT and namespace parsing Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 009/105] ACPI: EC: Rename ec_ecdt to more informative boot_ec Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 010/105] ACPI: EC: first_ec is better to be acpi_ec than acpi_device Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 011/105] ACPI: EC: Cleanup of EC initialization Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 012/105] ACPI: EC: Block queries until EC is fully initialized Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 013/105] asus-laptop: use acpi_evaluate_integer instead of read_acpi_int Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 014/105] asus-laptop: clean write_status Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 015/105] asus-laptop: add GLED Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 016/105] asus-laptop: add wapf param Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 017/105] asus-laptop: version bump Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 018/105] ACPI: sbs: use EC rather than I2C Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 019/105] ACPI: sbs: remove I2C Kconfig dependency Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 020/105] ACPI: sbs: remove I2C Makefile hooks Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 021/105] ACPI: sbs: Debug messages correction/improvement Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 022/105] ACPI: sbs: Common interface with CM battery Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 023/105] ACPI: sbs: remove i2c_ec.[ch] Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 024/105] ACPI: ibm-acpi: kill trailing whitespace Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 025/105] ACPI: ibm-acpi: rename some identifiers Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 026/105] ACPI: ibm-acpi: add header file Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 027/105] ACPI: ibm-acpi: organize code Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 028/105] ACPI: ibm-acpi: update copyright notice Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 029/105] ACPI: ibm-acpi: update documentation Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 031/105] ACPI: dock: use NULL for pointer Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 033/105] ACPI: thinkpad-acpi: cleanup Kconfig for thinkpad-acpi Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 034/105] ACPI: thinkpad-acpi: add compatibility MODULE_ALIAS entry Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 035/105] ACPI: thinkpad-acpi: cleanup after rename Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 036/105] ACPI: thinkpad-acpi: update MAINTAINERS Len Brown
2007-04-29  4:50       ` Len Brown
     [not found]         ` <11778223411658-git-send-email-len.brown@intel.com>
     [not found]           ` <11778223412672-git-send-email-len.brown@intel.com>
     [not found]             ` <11778223423-git-send-email-len.brown@intel.com>
     [not found]               ` <1177822343712-git-send-email-len.brown@intel.com>
     [not found]                 ` <11778223442065-git-send-email-len.brown@intel.com>
     [not found]                   ` <11778223452843-git-send-email-len.brown@intel.com>
     [not found]                     ` <11778223461282-git-send-email-len.brown@intel.com>
     [not found]                       ` <11778223472316-git-send-email-len.brown@intel.com>
2007-04-29  4:50     ` [PATCH 046/105] ACPI: thinkpad-acpi: rename register_ibmacpi_subdriver Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 047/105] ACPI: thinkpad-acpi: rename one stray use of ibm-acpi in a comment Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 048/105] ACPI: thinkpad-acpi: rename module glue Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 049/105] ACPI: thinkpad-acpi: rename thinkpad constants Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 050/105] ACPI: thinkpad-acpi: update fan firmware documentation Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 051/105] ACPI: thinkpad-acpi: add debug mode Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 052/105] ACPI: thinkpad-acpi: clean up probing and move init to subdrivers Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 053/105] ACPI: thinkpad-acpi: add subdriver debug statements Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 054/105] ACPI: thinkpad-acpi: uncouple subdriver init from ibms struct Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 055/105] ACPI: thinkpad-acpi: improve thinkpad detection Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 056/105] ACPI: thinkpad-acpi: use bitfields to hold subdriver flags Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 057/105] ACPI: thinkpad-acpi: use bitfields for module flags Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 058/105] ACPI: thinkpad-acpi: prepare for device model conversion Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:50     ` [PATCH 059/105] ACPI: thinkpad-acpi: mark acpi helper functions __must_check Len Brown
2007-04-29  4:50       ` Len Brown
2007-04-29  4:51     ` [PATCH 060/105] ACPI: thinkpad-acpi: clean up hotkey subdriver Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 061/105] ACPI: thinkpad-acpi: cleanup bluetooth and wan for sysfs conversion Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 062/105] ACPI: thinkpad-acpi: cleanup video subdriver Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 063/105] ACPI: thinkpad-acpi: clean up CMOS commands subdriver Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 064/105] ACPI: thinkpad-acpi: cleanup thermal subdriver for sysfs conversion Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 065/105] ACPI: thinkpad-acpi: improve fan watchdog messages Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 066/105] ACPI: Disable MSI on request of FADT Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 067/105] ACPI: Improve acpi debug documentation Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 068/105] ACPI: thinkpad-acpi: register with the device model Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 069/105] ACPI: thinkpad-acpi: driver sysfs conversion Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 070/105] ACPI: thinkpad-acpi: add infrastructure for the sysfs device attributes Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 071/105] ACPI: thinkpad-acpi: protect fan and hotkey data structures Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 072/105] ACPI: thinkpad-acpi: add sysfs support to the thermal subdriver Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 073/105] ACPI: thinkpad-acpi: add sysfs support to fan subdriver Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 074/105] ACPI: thinkpad-acpi: add a safety net for TPEC fan control mode Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 075/105] ACPI: thinkpad-acpi: add sysfs support to the cmos command subdriver Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 076/105] ACPI: thinkpad-acpi: update brightness sysfs interface support Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 077/105] ACPI: remove duplicate include Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 078/105] ACPI: Remove duplicate definitions for _STA bits Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 079/105] ACPI: use _STA bit names rather than 0x0F Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 080/105] ACPI: correct pathname in comment Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 081/105] ACPI: word-smith kconfig help Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 082/105] ACPI: make /proc/acpi/wakeup more useful Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 083/105] ACPI: prevent ACPI quirk warning mass spamming in logs Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  9:58         ` Andi Kleen
2007-04-29  4:51     ` [PATCH 084/105] ACPI: Remove a warning about unused variable in !CONFIG_ACPI compilation Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  9:59         ` Andi Kleen
2007-04-29  4:51     ` [PATCH 085/105] ACPICA: clear fields reserved before FADT r3 Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 086/105] ACPI: thinkpad-acpi: add a fan-control feature master toggle Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 087/105] ACPI: thinkpad-acpi: do not arm fan watchdog if it would not work Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 088/105] ACPI: thinkpad-acpi: fix a fan watchdog invocation Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 089/105] ACPI: thinkpad-acpi: map ENXIO to EINVAL for fan sysfs Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 090/105] ACPI: thinkpad-acpi: improve fan control documentation Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 091/105] ACPI: thinkpad-acpi: improve debugging for acpi helpers Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 092/105] ACPI: thinkpad-acpi: improve dock subdriver initialization Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 093/105] ACPI: thinkpad-acpi: add sysfs support to hotkey subdriver Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 094/105] ACPI: thinkpad-acpi: add sysfs support to wan and bluetooth subdrivers Len Brown
2007-04-29  4:51       ` Len Brown
2007-04-29  4:51     ` [PATCH 095/105] thinkpad-acpi: make drivers/misc/thinkpad_acpi:fan_mutex static Len Brown
2007-04-29  4:51       ` Len Brown
     [not found]         ` <11778223931192-git-send-email-len.brown@intel.com>
     [not found]           ` <11778223942367-git-send-email-len.brown@intel.com>
     [not found]             ` <11778223942377-git-send-email-len.brown@intel.com>
     [not found]               ` <1177822395384-git-send-email-len.brown@intel.com>
     [not found]                 ` <11778223963095-git-send-email-len.brown@intel.com>
     [not found]                   ` <11778223972558-git-send-email-len.brown@intel.com>
     [not found]                     ` <11778223981263-git-send-email-len.brown@intel.com>
     [not found]                       ` <117782239917-git-send-email-len.brown@intel.com>
2007-04-29  4:51     ` [PATCH 105/105] sonypi: use mutex instead of semaphore Len Brown
2007-04-29  4:51       ` Len Brown
2007-05-01  2:19 ` ACPI patches for 2.6.22 merge window Mattia Dongili
2007-05-10  6:44   ` Len Brown

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.