public inbox for linux-acpi@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/21] ACPI: ibm-acpi: cleanups, extended fan/thermal support
@ 2006-11-25 20:41 Henrique de Moraes Holschuh
  2006-11-25 20:42 ` [PATCH 01/21] ACPI: ibm-acpi: do not use / in driver names Henrique de Moraes Holschuh
                   ` (10 more replies)
  0 siblings, 11 replies; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-11-25 20:41 UTC (permalink / raw)
  To: len.brown; +Cc: ibm-acpi-devel, linux-acpi


This patch series contains the ibm-acpi devel queue for 2006-11-25.
Please merge for acpi-test.

Patch 1 fixes sub-driver naming so that it doesn't get in the way of
a ACPI sysfs conversion work.

Patch 2 just does some Lindent housekeeping work, as Len said he likes
code to be as Lindent-clean as possible.

Patches 3-5 extend thermal support for the new thinkpads, and updates
thermal docs.

Patches 6-13 extend fan support for new thinkpads, so people will stop
using ecdump to directly modify EC registers ;-)

Patches 14-15 implement a work-around for a bug in the EC firmware in
certain thinkpads, see
http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Bug:_Fan_control_loop_status_is_not_initialized

Patch 16 adds a watchdog functionality for fan control that has been
requested by developers of userspace fan control utilities.  Many
thinkpads have very annoying out-of-the-box fan behaviour, so userspace
fan control is quite widespread among T4x owners, for example.

Patch 17 adds support for SATA ultrabay (advanced ultrabay), found in
*60 and *61 x/t/z-series.

Patch 18 makes ibm-acpi non-generic bay support optional.

Patch 19 refactors backlight support so that it is in line with 
the rest of the ibm-acpi driver code.

Patches 20-21 are just housekeeping.

This patch series is available for git pull from:
git://repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git branch
for-upstream/acpi-test.

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh

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

* [PATCH 01/21] ACPI: ibm-acpi: do not use / in driver names
  2006-11-25 20:41 [PATCH 00/21] ACPI: ibm-acpi: cleanups, extended fan/thermal support Henrique de Moraes Holschuh
@ 2006-11-25 20:42 ` Henrique de Moraes Holschuh
  2006-11-29  9:08   ` Zhang Rui
  2006-11-25 20:42 ` [PATCH 03/21] ACPI: ibm-acpi: Use a enum to select the thermal sensor reading strategy Henrique de Moraes Holschuh
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-11-25 20:42 UTC (permalink / raw)
  To: len.brown; +Cc: ibm-acpi-devel, linux-acpi

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

ibm-acpi uses sub-device names like ibm/hotkey, which get in the way of
a sysfs conversion.  Fix it to use ibm_hotkey instead.  Thanks to Zhang
Rui for noticing this.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
---

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

diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 9658253..9baae34 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -1854,7 +1854,7 @@ static int __init register_driver(struct
 	}
 
 	memset(ibm->driver, 0, sizeof(struct acpi_driver));
-	sprintf(ibm->driver->name, "%s/%s", IBM_NAME, ibm->name);
+	sprintf(ibm->driver->name, "%s_%s", IBM_NAME, ibm->name);
 	ibm->driver->ids = ibm->hid;
 	ibm->driver->ops.add = &ibm_device_add;
 

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

* [PATCH 02/21] ACPI: ibm-acpi: trivial Lindent cleanups
       [not found] ` <20061125204155.6604.35338.stgit-H32KNTuDSMjdPi8JTuvWk31TOOPCyuNQ5NbjCUgZEJk@public.gmane.org>
@ 2006-11-25 20:42   ` Henrique de Moraes Holschuh
  2006-11-25 20:43   ` [PATCH 04/21] ACPI: ibm-acpi: Implement direct-ec-access thermal reading modes for up to 16 sensors Henrique de Moraes Holschuh
                     ` (11 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-11-25 20:42 UTC (permalink / raw)
  To: len.brown-ral2JQCrhuEAvxtiuMwx3w
  Cc: ibm-acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA

From: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>

This patch just makes drives/acpi/ibm-acpi.c Lindent-clean, as requested by
Len Brown.

Signed-off-by: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>
---

 drivers/acpi/ibm_acpi.c |   24 ++++++++++++------------
 1 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 9baae34..622626b 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -584,8 +584,7 @@ static int wan_status(void)
 {
 	int status;
 
-	if (!wan_supported ||
-	    !acpi_evalf(hkey_handle, &status, "GWAN", "d"))
+	if (!wan_supported || !acpi_evalf(hkey_handle, &status, "GWAN", "d"))
 		status = 0;
 
 	return status;
@@ -910,6 +909,7 @@ static int _sta(acpi_handle handle)
 
 	return status;
 }
+
 #ifdef CONFIG_ACPI_IBM_DOCK
 #define dock_docked() (_sta(dock_handle) & 1)
 
@@ -1386,12 +1386,12 @@ static int brightness_offset = 0x31;
 
 static int brightness_get(struct backlight_device *bd)
 {
-       u8 level;
-       if (!acpi_ec_read(brightness_offset, &level))
-               return -EIO;
+	u8 level;
+	if (!acpi_ec_read(brightness_offset, &level))
+		return -EIO;
 
-       level &= 0x7;
-       return level;
+	level &= 0x7;
+	return level;
 }
 
 static int brightness_read(char *p)
@@ -1992,10 +1992,10 @@ IBM_PARAM(volume);
 IBM_PARAM(fan);
 
 static struct backlight_properties ibm_backlight_data = {
-        .owner          = THIS_MODULE,
-        .get_brightness = brightness_get,
-        .update_status  = brightness_update_status,
-        .max_brightness = 7,
+	.owner = THIS_MODULE,
+	.get_brightness = brightness_get,
+	.update_status = brightness_update_status,
+	.max_brightness = 7,
 };
 
 static void acpi_ibm_exit(void)
@@ -2074,7 +2074,7 @@ static int __init acpi_ibm_init(void)
 
 	ibm_backlight_device = backlight_device_register("ibm", NULL,
 							 &ibm_backlight_data);
-        if (IS_ERR(ibm_backlight_device)) {
+	if (IS_ERR(ibm_backlight_device)) {
 		printk(IBM_ERR "Could not register ibm backlight device\n");
 		ibm_backlight_device = NULL;
 		acpi_ibm_exit();

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

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

* [PATCH 03/21] ACPI: ibm-acpi: Use a enum to select the thermal sensor reading strategy
  2006-11-25 20:41 [PATCH 00/21] ACPI: ibm-acpi: cleanups, extended fan/thermal support Henrique de Moraes Holschuh
  2006-11-25 20:42 ` [PATCH 01/21] ACPI: ibm-acpi: do not use / in driver names Henrique de Moraes Holschuh
@ 2006-11-25 20:42 ` Henrique de Moraes Holschuh
  2006-11-25 20:44 ` [PATCH 09/21] ACPI: ibm-acpi: cleanup fan_write Henrique de Moraes Holschuh
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-11-25 20:42 UTC (permalink / raw)
  To: len.brown; +Cc: ibm-acpi-devel, linux-acpi

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

This patch consolidades all decisions regarding the strategy to be used to
read thinkpad thermal sensors into a single enum, and refactors the
thermal sensor reading code to use a much more readable (and easier to
extend) switch() construct, in a separate function.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
---

 drivers/acpi/ibm_acpi.c |   90 ++++++++++++++++++++++++++++++++++-------------
 1 files changed, 65 insertions(+), 25 deletions(-)

diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 622626b..3a8f223 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -217,6 +217,17 @@ IBM_HANDLE(sfan, ec, "SFAN",	/* 570 */
 #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 */
+};
+
+#define IBMACPI_MAX_THERMAL_SENSORS 8	/* Max thermal sensors supported */
+struct ibm_thermal_sensors_struct {
+	s32 temp[IBMACPI_MAX_THERMAL_SENSORS];
+};
+
 struct ibm_struct {
 	char *name;
 	char param[32];
@@ -1275,50 +1286,79 @@ static int acpi_ec_write(int i, u8 v)
 	return 1;
 }
 
-static int thermal_tmp_supported;
-static int thermal_updt_supported;
+static enum thermal_access_mode thermal_read_mode;
 
 static int thermal_init(void)
 {
-	/* temperatures not supported on 570, G4x, R30, R31, R32 */
-	thermal_tmp_supported = acpi_evalf(ec_handle, NULL, "TMP7", "qv");
-
-	/* 600e/x, 770e, 770x */
-	thermal_updt_supported = acpi_evalf(ec_handle, NULL, "UPDT", "qv");
+	if (acpi_evalf(ec_handle, NULL, "TMP7", "qv")) {
+		if (acpi_evalf(ec_handle, NULL, "UPDT", "qv")) {
+			/* 600e/x, 770e, 770x */
+			thermal_read_mode = IBMACPI_THERMAL_ACPI_UPDT;
+		} else {
+			/* Standard ACPI TMPx access, max 8 sensors */
+			thermal_read_mode = IBMACPI_THERMAL_ACPI_TMP07;
+		}
+	} else {
+		/* temperatures not supported on 570, G4x, R30, R31, R32 */
+		thermal_read_mode = IBMACPI_THERMAL_NONE;
+	}
 
 	return 0;
 }
 
-static int thermal_read(char *p)
+static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s)
 {
-	int len = 0;
+	int i, t;
+	char tmpi[] = "TMPi";
 
-	if (!thermal_tmp_supported)
-		len += sprintf(p + len, "temperatures:\tnot supported\n");
-	else {
-		int i, t;
-		char tmpi[] = "TMPi";
-		s8 tmp[8];
+	if (!s)
+		return -EINVAL;
 
-		if (thermal_updt_supported)
-			if (!acpi_evalf(ec_handle, NULL, "UPDT", "v"))
+	switch (thermal_read_mode) {
+	case IBMACPI_THERMAL_ACPI_UPDT:
+		if (!acpi_evalf(ec_handle, NULL, "UPDT", "v"))
+			return -EIO;
+		for (i = 0; i < 8; i++) {
+			tmpi[3] = '0' + i;
+			if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
 				return -EIO;
+			s->temp[i] = (t - 2732) * 100;
+		}
+		return 8;
 
+	case IBMACPI_THERMAL_ACPI_TMP07:
 		for (i = 0; i < 8; i++) {
 			tmpi[3] = '0' + i;
 			if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
 				return -EIO;
-			if (thermal_updt_supported)
-				tmp[i] = (t - 2732 + 5) / 10;
-			else
-				tmp[i] = t;
+			s->temp[i] = t * 1000;
 		}
+		return 8;
 
-		len += sprintf(p + len,
-			       "temperatures:\t%d %d %d %d %d %d %d %d\n",
-			       tmp[0], tmp[1], tmp[2], tmp[3],
-			       tmp[4], tmp[5], tmp[6], tmp[7]);
+	case IBMACPI_THERMAL_NONE:
+	default:
+		return 0;
 	}
+}
+
+static int thermal_read(char *p)
+{
+	int len = 0;
+	int n, i;
+	struct ibm_thermal_sensors_struct t;
+
+	n = thermal_get_sensors(&t);
+	if (unlikely(n < 0))
+		return n;
+
+	len += sprintf(p + len, "temperatures:\t");
+
+	if (n > 0) {
+		for (i = 0; i < (n - 1); i++)
+			len += sprintf(p + len, "%d ", t.temp[i] / 1000);
+		len += sprintf(p + len, "%d\n", t.temp[i] / 1000);
+	} else
+		len += sprintf(p + len, "not supported\n");
 
 	return len;
 }

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

* [PATCH 04/21] ACPI: ibm-acpi: Implement direct-ec-access thermal reading modes for up to 16 sensors
       [not found] ` <20061125204155.6604.35338.stgit-H32KNTuDSMjdPi8JTuvWk31TOOPCyuNQ5NbjCUgZEJk@public.gmane.org>
  2006-11-25 20:42   ` [PATCH 02/21] ACPI: ibm-acpi: trivial Lindent cleanups Henrique de Moraes Holschuh
@ 2006-11-25 20:43   ` Henrique de Moraes Holschuh
  2006-11-25 20:43   ` [PATCH 05/21] ACPI: ibm-acpi: document thermal sensor locations for the A31 Henrique de Moraes Holschuh
                     ` (10 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-11-25 20:43 UTC (permalink / raw)
  To: len.brown-ral2JQCrhuEAvxtiuMwx3w
  Cc: ibm-acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA

From: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>

This patch extends ibm-acpi to support reading thermal sensors directly
through ACPI EC register access.  It uses a DMI match to detect ThinkPads
with a new-style embedded controller, that are known to have forward-
compatible register maps and use 0x00 to fill in non-used registers and
export thermal sensors at EC offsets 0x78-7F and 0xC0-C7.

Direct ACPI EC register access is implemented for 8-sensor and 16-sensor
new-style ThinkPad controller firmwares as an experimental feature.  The
code does some limited sanity checks on the temperatures read through EC
access, and will default to the old ACPI TMP0-7 mode if anything is amiss.

Userspace ABI is not changed for 8 sensors, but /proc/acpi/ibm/thermal is
extended for 16 sensors if the firmware supports 16 sensors.

A documentation update is also provided.

The information about the ThinkPad register map was determined by studying
ibm-acpi "ecdump" output from various ThinkPad models, submitted by
subscribers of the linux-thinkpad mailinglist.  Futher information was
gathered from the DSDT tables, as they describe the EC register map in
recent ThinkPads.

DSDT source shows that TMP0-7 access and direct register access are
actually the same thing on these firmwares, but unfortunately IBM never
did update their DSDT EC register map to export TMP8-TMP15 for the second
range of sensors.

Signed-off-by: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>
---

 Documentation/ibm-acpi.txt |   55 ++++++++++++++++++++------
 drivers/acpi/ibm_acpi.c    |   93 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 134 insertions(+), 14 deletions(-)

diff --git a/Documentation/ibm-acpi.txt b/Documentation/ibm-acpi.txt
index e50595b..30f09e7 100644
--- a/Documentation/ibm-acpi.txt
+++ b/Documentation/ibm-acpi.txt
@@ -398,25 +398,56 @@ Temperature sensors -- /proc/acpi/ibm/th
 
 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. Some
-readings may not be valid, e.g. may show large negative values. For
-example, on the X40, a typical output may be:
+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.
+
+EXPERIMENTAL: The 16-sensors 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.  When EXPERIMENTAL
+mode is enabled, reading the first 8 sensors on newer ThinkPads will
+also use an new experimental thermal sensor access mode.
+
+For example, on the X40, a typical output may be:
 temperatures:   42 42 45 41 36 -128 33 -128
 
-Thomas Gruber took his R51 apart and traced all six active sensors in
-his laptop (the location of sensors may vary on other models):
+EXPERIMENTAL: On the T43/p, a typical output may be:
+temperatures:   48 48 36 52 38 -128 31 -128 48 52 48 -128 -128 -128 -128 -128
+
+The mapping of thermal sensors to physical locations varies depending on
+system-board model (and thus, on ThinkPad model).
+
+http://thinkwiki.org/wiki/Thermal_Sensors is a public wiki page that
+tries to track down these locations for various models.
+
+Most (newer?) models seem to follow this pattern:
 
 1:  CPU
-2:  Mini PCI Module
-3:  HDD
+2:  (depends on model)
+3:  (depends on model)
 4:  GPU
-5:  Battery
-6:  N/A
-7:  Battery
-8:  N/A
+5:  Main battery: main sensor
+6:  Bay battery: main sensor
+7:  Main battery: secondary sensor
+8:  Bay battery: secondary sensor
+9-15: (depends on model)
+
+For the R51 (source: Thomas Gruber):
+2:  Mini-PCI
+3:  Internal HDD
+
+For the T43, T43/p (source: Shmidoax/Thinkwiki.org)
+http://thinkwiki.org/wiki/Thermal_Sensors#ThinkPad_T43.2C_T43p
+2:  System board, left side (near PCMCIA slot), reported as HDAPS temp
+3:  PCMCIA slot
+9:  MCH (northbridge) to DRAM Bus
+10: ICH (southbridge), under Mini-PCI card, under touchpad
+11: Power regulator, underside of system board, below F2 key
 
-No commands can be written to this file.
 
 EXPERIMENTAL: Embedded controller register dump -- /proc/acpi/ibm/ecdump
 ------------------------------------------------------------------------
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 3a8f223..491c413 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -80,6 +80,7 @@
 #include <linux/proc_fs.h>
 #include <linux/backlight.h>
 #include <asm/uaccess.h>
+#include <linux/dmi.h>
 
 #include <acpi/acpi_drivers.h>
 #include <acpi/acnamesp.h>
@@ -221,13 +222,17 @@ 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 8	/* Max thermal sensors supported */
+#define IBMACPI_MAX_THERMAL_SENSORS 16	/* Max thermal sensors supported */
 struct ibm_thermal_sensors_struct {
 	s32 temp[IBMACPI_MAX_THERMAL_SENSORS];
 };
 
+static int ibm_thinkpad_ec_found;
+
 struct ibm_struct {
 	char *name;
 	char param[32];
@@ -1290,7 +1295,52 @@ static enum thermal_access_mode thermal_
 
 static int thermal_init(void)
 {
-	if (acpi_evalf(ec_handle, NULL, "TMP7", "qv")) {
+	u8 t, ta1, ta2;
+	int i;
+	int acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv");
+
+	if (ibm_thinkpad_ec_found && experimental) {
+		/*
+		 * Direct EC access mode: sensors at registers
+		 * 0x78-0x7F, 0xC0-0xC7.  Registers return 0x00 for
+		 * non-implemented, thermal sensors return 0x80 when
+		 * not available
+		 */
+
+		ta1 = ta2 = 0;
+		for (i = 0; i < 8; i++) {
+			if (likely(acpi_ec_read(0x78 + i, &t))) {
+				ta1 |= t;
+			} else {
+				ta1 = 0;
+				break;
+			}
+			if (likely(acpi_ec_read(0xC0 + i, &t))) {
+				ta2 |= t;
+			} else {
+				ta1 = 0;
+				break;
+			}
+		}
+		if (ta1 == 0) {
+			/* This is sheer paranoia, but we handle it anyway */
+			if (acpi_tmp7) {
+				printk(IBM_ERR
+				       "ThinkPad ACPI EC access misbehaving, "
+				       "falling back to ACPI TMPx access mode\n");
+				thermal_read_mode = IBMACPI_THERMAL_ACPI_TMP07;
+			} else {
+				printk(IBM_ERR
+				       "ThinkPad ACPI EC access misbehaving, "
+				       "disabling thermal sensors access\n");
+				thermal_read_mode = IBMACPI_THERMAL_NONE;
+			}
+		} else {
+			thermal_read_mode =
+			    (ta2 != 0) ?
+			    IBMACPI_THERMAL_TPEC_16 : IBMACPI_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;
@@ -1309,12 +1359,30 @@ static int thermal_init(void)
 static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s)
 {
 	int i, t;
+	s8 tmp;
 	char tmpi[] = "TMPi";
 
 	if (!s)
 		return -EINVAL;
 
 	switch (thermal_read_mode) {
+#if IBMACPI_MAX_THERMAL_SENSORS >= 16
+	case IBMACPI_THERMAL_TPEC_16:
+		for (i = 0; i < 8; i++) {
+			if (!acpi_ec_read(0xC0 + i, &tmp))
+				return -EIO;
+			s->temp[i + 8] = tmp * 1000;
+		}
+		/* fallthrough */
+#endif
+	case IBMACPI_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;
+
 	case IBMACPI_THERMAL_ACPI_UPDT:
 		if (!acpi_evalf(ec_handle, NULL, "UPDT", "v"))
 			return -EIO;
@@ -2051,6 +2119,24 @@ static void acpi_ibm_exit(void)
 	remove_proc_entry(IBM_DIR, acpi_root_dir);
 }
 
+static int __init check_dmi_for_ec(void)
+{
+	struct dmi_device *dev = NULL;
+
+	/*
+	 * 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 (strstr(dev->name, "IBM ThinkPad Embedded Controller"))
+			return 1;
+	}
+	return 0;
+}
+
 static int __init acpi_ibm_init(void)
 {
 	int ret, i;
@@ -2070,6 +2156,9 @@ static int __init acpi_ibm_init(void)
 		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);

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

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

* [PATCH 05/21] ACPI: ibm-acpi: document thermal sensor locations for the A31
       [not found] ` <20061125204155.6604.35338.stgit-H32KNTuDSMjdPi8JTuvWk31TOOPCyuNQ5NbjCUgZEJk@public.gmane.org>
  2006-11-25 20:42   ` [PATCH 02/21] ACPI: ibm-acpi: trivial Lindent cleanups Henrique de Moraes Holschuh
  2006-11-25 20:43   ` [PATCH 04/21] ACPI: ibm-acpi: Implement direct-ec-access thermal reading modes for up to 16 sensors Henrique de Moraes Holschuh
@ 2006-11-25 20:43   ` Henrique de Moraes Holschuh
  2006-11-25 20:43   ` [PATCH 06/21] ACPI: ibm-acpi: prepare to cleanup fan_read and fan_write Henrique de Moraes Holschuh
                     ` (9 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-11-25 20:43 UTC (permalink / raw)
  To: len.brown-ral2JQCrhuEAvxtiuMwx3w
  Cc: ibm-acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA

From: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>

The A31 has a very atypical layout, so I separated its thermal sensors
location in a separate patch.

Signed-off-by: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>
---

 Documentation/ibm-acpi.txt |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/Documentation/ibm-acpi.txt b/Documentation/ibm-acpi.txt
index 30f09e7..333b8eb 100644
--- a/Documentation/ibm-acpi.txt
+++ b/Documentation/ibm-acpi.txt
@@ -448,6 +448,17 @@ http://thinkwiki.org/wiki/Thermal_Sensor
 10: ICH (southbridge), under Mini-PCI card, under touchpad
 11: Power regulator, underside of system board, below F2 key
 
+The A31 has a very atypical layout for the thermal sensors
+(source: Milos Popovic, http://thinkwiki.org/wiki/Thermal_Sensors#ThinkPad_A31)
+1:  CPU
+2:  Main Battery: main sensor
+3:  Power Converter
+4:  Bay Battery: main sensor
+5:  MCH (northbridge)
+6:  PCMCIA/ambient
+7:  Main Battery: secondary sensor
+8:  Bay Battery: secondary sensor
+
 
 EXPERIMENTAL: Embedded controller register dump -- /proc/acpi/ibm/ecdump
 ------------------------------------------------------------------------

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

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

* [PATCH 06/21] ACPI: ibm-acpi: prepare to cleanup fan_read and fan_write
       [not found] ` <20061125204155.6604.35338.stgit-H32KNTuDSMjdPi8JTuvWk31TOOPCyuNQ5NbjCUgZEJk@public.gmane.org>
                     ` (2 preceding siblings ...)
  2006-11-25 20:43   ` [PATCH 05/21] ACPI: ibm-acpi: document thermal sensor locations for the A31 Henrique de Moraes Holschuh
@ 2006-11-25 20:43   ` Henrique de Moraes Holschuh
  2006-11-25 20:44   ` [PATCH 07/21] ACPI: ibm-acpi: clean up fan_read Henrique de Moraes Holschuh
                     ` (8 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-11-25 20:43 UTC (permalink / raw)
  To: len.brown-ral2JQCrhuEAvxtiuMwx3w
  Cc: ibm-acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA

From: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>

This patch lays some groundwork for a fan_read and fan_write cleanup in the
next patches.  To do so, it provides a new fan_init initializer, and also some
constants (through enums).

Signed-off-by: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>
---

 drivers/acpi/ibm_acpi.c |   81 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 79 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 491c413..4c836e2 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -231,6 +231,31 @@ struct ibm_thermal_sensors_struct {
 	s32 temp[IBMACPI_MAX_THERMAL_SENSORS];
 };
 
+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 */
+};
+
+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 */
+};
+
 static int ibm_thinkpad_ec_found;
 
 struct ibm_struct {
@@ -1659,8 +1684,59 @@ static int volume_write(char *buf)
 	return 0;
 }
 
-static int fan_status_offset = 0x2f;
-static int fan_rpm_offset = 0x84;
+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_init(void)
+{
+	u8 status;
+
+	fan_status_access_mode = IBMACPI_FAN_NONE;
+	fan_control_access_mode = IBMACPI_FAN_WR_NONE;
+	fan_control_commands = 0;
+
+	if (gfan_handle) {
+		/* 570, 600e/x, 770e, 770x */
+		fan_status_access_mode = IBMACPI_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, &status))) {
+			fan_status_access_mode = IBMACPI_FAN_RD_TPEC;
+		} else {
+			printk(IBM_ERR
+			       "ThinkPad ACPI EC access misbehaving, "
+			       "fan status and control unavailable\n");
+			return 0;
+		}
+	}
+
+	if (sfan_handle) {
+		/* 570, 770x-JL */
+		fan_control_access_mode = IBMACPI_FAN_WR_ACPI_SFAN;
+		fan_control_commands |= IBMACPI_FAN_CMD_LEVEL;
+	} else {
+		if (!gfan_handle) {
+			/* gfan without sfan means no fan control */
+			/* all other models implement TP EC 0x2f control */
+
+			if (fans_handle) {
+				/* X31, X40 */
+				fan_control_access_mode =
+				    IBMACPI_FAN_WR_ACPI_FANS;
+				fan_control_commands |=
+				    IBMACPI_FAN_CMD_SPEED |
+				    IBMACPI_FAN_CMD_ENABLE;
+			} else {
+				fan_control_access_mode = IBMACPI_FAN_WR_TPEC;
+				fan_control_commands |= IBMACPI_FAN_CMD_ENABLE;
+			}
+		}
+	}
+
+	return 0;
+}
 
 static int fan_read(char *p)
 {
@@ -1849,6 +1925,7 @@ static struct ibm_struct ibms[] = {
 	 .name = "fan",
 	 .read = fan_read,
 	 .write = fan_write,
+	 .init = fan_init,
 	 .experimental = 1,
 	 },
 };

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

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

* [PATCH 07/21] ACPI: ibm-acpi: clean up fan_read
       [not found] ` <20061125204155.6604.35338.stgit-H32KNTuDSMjdPi8JTuvWk31TOOPCyuNQ5NbjCUgZEJk@public.gmane.org>
                     ` (3 preceding siblings ...)
  2006-11-25 20:43   ` [PATCH 06/21] ACPI: ibm-acpi: prepare to cleanup fan_read and fan_write Henrique de Moraes Holschuh
@ 2006-11-25 20:44   ` Henrique de Moraes Holschuh
  2006-11-25 20:44   ` [PATCH 08/21] ACPI: ibm-acpi: break fan_read into separate functions Henrique de Moraes Holschuh
                     ` (7 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-11-25 20:44 UTC (permalink / raw)
  To: len.brown-ral2JQCrhuEAvxtiuMwx3w
  Cc: ibm-acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA

From: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>

This patch cleans up fan_read so that it is much easier to read and
extend.

The patch fixes the userspace ABI to return "status: not supported" (like
all other ibm-acpi functions) when neither fan status or fan control are
possible.

It also fixes the userspace ABI to return EIO if ACPI access to the EC
fails, instead of returning "status: unreadable" or "speed: unreadable".

Signed-off-by: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>
---

 drivers/acpi/ibm_acpi.c |   40 ++++++++++++++++++++++++----------------
 1 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 4c836e2..ef8ac01 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -1741,40 +1741,48 @@ static int fan_init(void)
 static int fan_read(char *p)
 {
 	int len = 0;
-	int s;
 	u8 lo, hi, status;
 
-	if (gfan_handle) {
+	switch (fan_status_access_mode) {
+	case IBMACPI_FAN_RD_ACPI_GFAN:
 		/* 570, 600e/x, 770e, 770x */
-		if (!acpi_evalf(gfan_handle, &s, NULL, "d"))
+		if (unlikely(!acpi_evalf(gfan_handle, &status, NULL, "d")))
 			return -EIO;
 
-		len += sprintf(p + len, "level:\t\t%d\n", s);
-	} else {
+		len += sprintf(p + len, "level:\t\t%d\n", status);
+
+		break;
+
+	case IBMACPI_FAN_RD_TPEC:
 		/* all except 570, 600e/x, 770e, 770x */
-		if (!acpi_ec_read(fan_status_offset, &status))
-			len += sprintf(p + len, "status:\t\tunreadable\n");
+		if (unlikely(!acpi_ec_read(fan_status_offset, &status)))
+			return -EIO;
 		else
 			len += sprintf(p + len, "status:\t\t%s\n",
 				       enabled(status, 7));
 
-		if (!acpi_ec_read(fan_rpm_offset, &lo) ||
-		    !acpi_ec_read(fan_rpm_offset + 1, &hi))
-			len += sprintf(p + len, "speed:\t\tunreadable\n");
+		if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) ||
+			     !acpi_ec_read(fan_rpm_offset + 1, &hi)))
+			return -EIO;
 		else
 			len += sprintf(p + len, "speed:\t\t%d\n",
 				       (hi << 8) + lo);
+
+		break;
+
+	case IBMACPI_FAN_NONE:
+	default:
+		len += sprintf(p + len, "status:\t\tnot supported\n");
 	}
 
-	if (sfan_handle)
-		/* 570, 770x-JL */
+	if (fan_control_commands & IBMACPI_FAN_CMD_LEVEL)
 		len += sprintf(p + len, "commands:\tlevel <level>"
 			       " (<level> is 0-7)\n");
-	if (!gfan_handle)
-		/* all except 570, 600e/x, 770e, 770x */
+
+	if (fan_control_commands & IBMACPI_FAN_CMD_ENABLE)
 		len += sprintf(p + len, "commands:\tenable, disable\n");
-	if (fans_handle)
-		/* X31, X40 */
+
+	if (fan_control_commands & IBMACPI_FAN_CMD_SPEED)
 		len += sprintf(p + len, "commands:\tspeed <speed>"
 			       " (<speed> is 0-65535)\n");
 

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

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

* [PATCH 08/21] ACPI: ibm-acpi: break fan_read into separate functions
       [not found] ` <20061125204155.6604.35338.stgit-H32KNTuDSMjdPi8JTuvWk31TOOPCyuNQ5NbjCUgZEJk@public.gmane.org>
                     ` (4 preceding siblings ...)
  2006-11-25 20:44   ` [PATCH 07/21] ACPI: ibm-acpi: clean up fan_read Henrique de Moraes Holschuh
@ 2006-11-25 20:44   ` Henrique de Moraes Holschuh
  2006-11-25 20:45   ` [PATCH 10/21] ACPI: ibm-acpi: document fan control Henrique de Moraes Holschuh
                     ` (6 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-11-25 20:44 UTC (permalink / raw)
  To: len.brown-ral2JQCrhuEAvxtiuMwx3w
  Cc: ibm-acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA

From: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>

This patch breaks fan_read mechanics into a generic function to get fan
status and speed, and leaves only the procfs interface code in fan_read.

Signed-off-by: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>
---

 drivers/acpi/ibm_acpi.c |   78 ++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 66 insertions(+), 12 deletions(-)

diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index ef8ac01..834485b 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -1738,36 +1738,90 @@ static int fan_init(void)
 	return 0;
 }
 
-static int fan_read(char *p)
+static int fan_get_status(u8 *status)
 {
-	int len = 0;
-	u8 lo, hi, status;
+	u8 s;
 
 	switch (fan_status_access_mode) {
 	case IBMACPI_FAN_RD_ACPI_GFAN:
 		/* 570, 600e/x, 770e, 770x */
-		if (unlikely(!acpi_evalf(gfan_handle, &status, NULL, "d")))
+
+		if (unlikely(!acpi_evalf(gfan_handle, &s, NULL, "d")))
 			return -EIO;
 
-		len += sprintf(p + len, "level:\t\t%d\n", status);
+		if (likely(status))
+			*status = s & 0x07;
 
 		break;
 
 	case IBMACPI_FAN_RD_TPEC:
 		/* all except 570, 600e/x, 770e, 770x */
-		if (unlikely(!acpi_ec_read(fan_status_offset, &status)))
+		if (unlikely(!acpi_ec_read(fan_status_offset, &s)))
 			return -EIO;
-		else
-			len += sprintf(p + len, "status:\t\t%s\n",
-				       enabled(status, 7));
 
+		if (likely(status))
+			*status = s;
+
+		break;
+
+	default:
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+static int fan_get_speed(unsigned int *speed)
+{
+	u8 hi, lo;
+
+	switch (fan_status_access_mode) {
+	case IBMACPI_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)))
 			return -EIO;
-		else
-			len += sprintf(p + len, "speed:\t\t%d\n",
-				       (hi << 8) + lo);
 
+		if (likely(speed))
+			*speed = (hi << 8) | lo;
+
+		break;
+
+	default:
+		return -ENXIO;
+	}
+
+	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, "level:\t\t%d\n", status);
+
+		break;
+
+	case IBMACPI_FAN_RD_TPEC:
+		/* all except 570, 600e/x, 770e, 770x */
+		if ((rc = fan_get_status(&status)) < 0)
+			return rc;
+
+		len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 7));
+
+		if ((rc = fan_get_speed(&speed)) < 0)
+			return rc;
+
+		len += sprintf(p + len, "speed:\t\t%d\n", speed);
 		break;
 
 	case IBMACPI_FAN_NONE:

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

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

* [PATCH 09/21] ACPI: ibm-acpi: cleanup fan_write
  2006-11-25 20:41 [PATCH 00/21] ACPI: ibm-acpi: cleanups, extended fan/thermal support Henrique de Moraes Holschuh
  2006-11-25 20:42 ` [PATCH 01/21] ACPI: ibm-acpi: do not use / in driver names Henrique de Moraes Holschuh
  2006-11-25 20:42 ` [PATCH 03/21] ACPI: ibm-acpi: Use a enum to select the thermal sensor reading strategy Henrique de Moraes Holschuh
@ 2006-11-25 20:44 ` Henrique de Moraes Holschuh
  2006-11-25 20:45 ` [PATCH 11/21] ACPI: ibm-acpi: extend fan status functions Henrique de Moraes Holschuh
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-11-25 20:44 UTC (permalink / raw)
  To: len.brown; +Cc: ibm-acpi-devel, linux-acpi

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

This patch cleans up fan_write so that it is much easier to read and
extend.  It separates the proc api handling from the operations themselves.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
---

 drivers/acpi/ibm_acpi.c |  147 ++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 125 insertions(+), 22 deletions(-)

diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 834485b..5258994 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -1843,40 +1843,143 @@ static int fan_read(char *p)
 	return len;
 }
 
-static int fan_write(char *buf)
+static int fan_set_level(int level)
 {
-	char *cmd;
-	int level, speed;
-
-	while ((cmd = next_cmd(&buf))) {
-		if (sfan_handle &&
-		    sscanf(cmd, "level %d", &level) == 1 &&
-		    level >= 0 && level <= 7) {
-			/* 570, 770x-JL */
+	switch (fan_control_access_mode) {
+	case IBMACPI_FAN_WR_ACPI_SFAN:
+		if (level >= 0 && level <= 7) {
 			if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level))
 				return -EIO;
-		} else if (!gfan_handle && strlencmp(cmd, "enable") == 0) {
-			/* all except 570, 600e/x, 770e, 770x */
-			if (!acpi_ec_write(fan_status_offset, 0x80))
-				return -EIO;
-		} else if (!gfan_handle && strlencmp(cmd, "disable") == 0) {
-			/* all except 570, 600e/x, 770e, 770x */
-			if (!acpi_ec_write(fan_status_offset, 0x00))
-				return -EIO;
-		} else if (fans_handle &&
-			   sscanf(cmd, "speed %d", &speed) == 1 &&
-			   speed >= 0 && speed <= 65535) {
-			/* X31, X40 */
+		} else
+			return -EINVAL;
+		break;
+
+	default:
+		return -ENXIO;
+	}
+	return 0;
+}
+
+static int fan_set_enable(void)
+{
+	switch (fan_control_access_mode) {
+	case IBMACPI_FAN_WR_ACPI_FANS:
+	case IBMACPI_FAN_WR_TPEC:
+		if (!acpi_ec_write(fan_status_offset, 0x80))
+			return -EIO;
+		break;
+
+	default:
+		return -ENXIO;
+	}
+	return 0;
+}
+
+static int fan_set_disable(void)
+{
+	switch (fan_control_access_mode) {
+	case IBMACPI_FAN_WR_ACPI_FANS:
+	case IBMACPI_FAN_WR_TPEC:
+		if (!acpi_ec_write(fan_status_offset, 0x00))
+			return -EIO;
+		break;
+
+	default:
+		return -ENXIO;
+	}
+	return 0;
+}
+
+static int fan_set_speed(int speed)
+{
+	switch (fan_control_access_mode) {
+	case IBMACPI_FAN_WR_ACPI_FANS:
+		if (speed >= 0 && speed <= 65535) {
 			if (!acpi_evalf(fans_handle, NULL, NULL, "vddd",
 					speed, speed, speed))
 				return -EIO;
 		} else
 			return -EINVAL;
-	}
+		break;
 
+	default:
+		return -ENXIO;
+	}
 	return 0;
 }
 
+static int fan_write_cmd_level(const char *cmd, int *rc)
+{
+	int level;
+
+	if (sscanf(cmd, "level %d", &level) != 1)
+		return 0;
+
+	if ((*rc = fan_set_level(level)) == -ENXIO)
+		printk(IBM_ERR "level command accepted for unsupported "
+		       "access mode %d", fan_control_access_mode);
+
+	return 1;
+}
+
+static int fan_write_cmd_enable(const char *cmd, int *rc)
+{
+	if (strlencmp(cmd, "enable") != 0)
+		return 0;
+
+	if ((*rc = fan_set_enable()) == -ENXIO)
+		printk(IBM_ERR "enable command accepted for unsupported "
+		       "access mode %d", fan_control_access_mode);
+
+	return 1;
+}
+
+static int fan_write_cmd_disable(const char *cmd, int *rc)
+{
+	if (strlencmp(cmd, "disable") != 0)
+		return 0;
+
+	if ((*rc = fan_set_disable()) == -ENXIO)
+		printk(IBM_ERR "disable command accepted for unsupported "
+		       "access mode %d", fan_control_access_mode);
+
+	return 1;
+}
+
+static int fan_write_cmd_speed(const char *cmd, int *rc)
+{
+	int speed;
+
+	if (sscanf(cmd, "speed %d", &speed) != 1)
+		return 0;
+
+	if ((*rc = fan_set_speed(speed)) == -ENXIO)
+		printk(IBM_ERR "speed command accepted for unsupported "
+		       "access mode %d", fan_control_access_mode);
+
+	return 1;
+}
+
+static int fan_write(char *buf)
+{
+	char *cmd;
+	int rc = 0;
+
+	while (!rc && (cmd = next_cmd(&buf))) {
+		if (!((fan_control_commands & IBMACPI_FAN_CMD_LEVEL) &&
+		      fan_write_cmd_level(cmd, &rc)) &&
+		    !((fan_control_commands & IBMACPI_FAN_CMD_ENABLE) &&
+		      (fan_write_cmd_enable(cmd, &rc) ||
+		       fan_write_cmd_disable(cmd, &rc))) &&
+		    !((fan_control_commands & IBMACPI_FAN_CMD_SPEED) &&
+		      fan_write_cmd_speed(cmd, &rc))
+		    )
+			rc = -EINVAL;
+	}
+
+	return rc;
+}
+
 static struct ibm_struct ibms[] = {
 	{
 	 .name = "driver",

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

* [PATCH 10/21] ACPI: ibm-acpi: document fan control
       [not found] ` <20061125204155.6604.35338.stgit-H32KNTuDSMjdPi8JTuvWk31TOOPCyuNQ5NbjCUgZEJk@public.gmane.org>
                     ` (5 preceding siblings ...)
  2006-11-25 20:44   ` [PATCH 08/21] ACPI: ibm-acpi: break fan_read into separate functions Henrique de Moraes Holschuh
@ 2006-11-25 20:45   ` Henrique de Moraes Holschuh
  2006-11-25 20:45   ` [PATCH 12/21] ACPI: ibm-acpi: fix and extend fan enable Henrique de Moraes Holschuh
                     ` (5 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-11-25 20:45 UTC (permalink / raw)
  To: len.brown-ral2JQCrhuEAvxtiuMwx3w
  Cc: ibm-acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA

From: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>

This patch documents the ThinkPad fan control strategies.  Source of the
data:

0. ibm-acpi source
1. DSDTs for various ThinkPads (770, X31, X40, X41, T43, A21m, T22)
2. http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues
3. http://thinkwiki.org/wiki/How_to_control_fan_speed
4. Various threads about windows fan control utilities in thinkpads.com

Signed-off-by: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>
---

 drivers/acpi/ibm_acpi.c |  110 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 108 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 5258994..ccbb17c 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -205,7 +205,7 @@ IBM_HANDLE(led, ec, "SLED",	/* 570 */
 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 */
+IBM_HANDLE(fans, ec, "FANS");	/* X31, X40, X41 */
 
 IBM_HANDLE(gfan, ec, "GFAN",	/* 570 */
 	   "\\FSPD",		/* 600e/x, 770e, 770x */
@@ -231,6 +231,106 @@ struct ibm_thermal_sensors_struct {
 	s32 temp[IBMACPI_MAX_THERMAL_SENSORS];
 };
 
+/*
+ * 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.
+ */
+
 enum fan_status_access_mode {
 	IBMACPI_FAN_NONE = 0,		/* No fan status or control */
 	IBMACPI_FAN_RD_ACPI_GFAN,	/* Use ACPI GFAN */
@@ -1722,7 +1822,7 @@ static int fan_init(void)
 			/* all other models implement TP EC 0x2f control */
 
 			if (fans_handle) {
-				/* X31, X40 */
+				/* X31, X40, X41 */
 				fan_control_access_mode =
 				    IBMACPI_FAN_WR_ACPI_FANS;
 				fan_control_commands |=
@@ -1742,6 +1842,9 @@ static int fan_get_status(u8 *status)
 {
 	u8 s;
 
+	/* TODO:
+	 * Add IBMACPI_FAN_RD_ACPI_FANS ? */
+
 	switch (fan_status_access_mode) {
 	case IBMACPI_FAN_RD_ACPI_GFAN:
 		/* 570, 600e/x, 770e, 770x */
@@ -1950,6 +2053,9 @@ static int fan_write_cmd_speed(const cha
 {
 	int speed;
 
+	/* TODO:
+	 * Support speed <low> <medium> <high> ? */
+
 	if (sscanf(cmd, "speed %d", &speed) != 1)
 		return 0;
 

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

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

* [PATCH 11/21] ACPI: ibm-acpi: extend fan status functions
  2006-11-25 20:41 [PATCH 00/21] ACPI: ibm-acpi: cleanups, extended fan/thermal support Henrique de Moraes Holschuh
                   ` (2 preceding siblings ...)
  2006-11-25 20:44 ` [PATCH 09/21] ACPI: ibm-acpi: cleanup fan_write Henrique de Moraes Holschuh
@ 2006-11-25 20:45 ` Henrique de Moraes Holschuh
  2006-11-25 20:46 ` [PATCH 13/21] ACPI: ibm-acpi: fix and extend fan control functions Henrique de Moraes Holschuh
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-11-25 20:45 UTC (permalink / raw)
  To: len.brown; +Cc: ibm-acpi-devel, linux-acpi

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

This patch fixes fan_read to return correct values for all fan access
modes.  It also implements some fan access mode status output that was
missing, and normalizes the proc fan abi to return consistent data across
all fan read/write modes.

Userspace ABI changes and extensions:
	1. Return status: enable/disable for *all* modes
	   (this actually improves compatibility with userspace utils!)
	2. Return level: auto and level: disengaged for EC 2f access mode
	3. Return level: <number> for EC 0x2f access mode
	4. Return level 0 as well as "disabled" in level-aware modes

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
---

 drivers/acpi/ibm_acpi.c |   21 ++++++++++++++++++---
 1 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index ccbb17c..2dc36e7 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -354,6 +354,11 @@ 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 int ibm_thinkpad_ec_found;
@@ -1910,8 +1915,9 @@ static int fan_read(char *p)
 		if ((rc = fan_get_status(&status)) < 0)
 			return rc;
 
-		len += sprintf(p + len, "level:\t\t%d\n", status);
-
+		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:
@@ -1919,12 +1925,21 @@ static int fan_read(char *p)
 		if ((rc = fan_get_status(&status)) < 0)
 			return rc;
 
-		len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 7));
+		len += sprintf(p + len, "status:\t\t%s\n",
+			       (status != 0) ? "enabled" : "disabled");
 
 		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:

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

* [PATCH 12/21] ACPI: ibm-acpi: fix and extend fan enable
       [not found] ` <20061125204155.6604.35338.stgit-H32KNTuDSMjdPi8JTuvWk31TOOPCyuNQ5NbjCUgZEJk@public.gmane.org>
                     ` (6 preceding siblings ...)
  2006-11-25 20:45   ` [PATCH 10/21] ACPI: ibm-acpi: document fan control Henrique de Moraes Holschuh
@ 2006-11-25 20:45   ` Henrique de Moraes Holschuh
  2006-11-25 20:47   ` [PATCH 16/21] ACPI: ibm-acpi: implement fan watchdog command Henrique de Moraes Holschuh
                     ` (4 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-11-25 20:45 UTC (permalink / raw)
  To: len.brown-ral2JQCrhuEAvxtiuMwx3w
  Cc: ibm-acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA

From: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>

This patch fix fan enable to attempt to do the right thing and not slow
down the fan if it is forced to the maximum speed.  It also extends fan
enable to work on older thinkpads.

ABI changes:
	1.  Support enable/disable for all level-based write access modes

Signed-off-by: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>
---

 drivers/acpi/ibm_acpi.c |   34 ++++++++++++++++++++++++++++++++--
 1 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 2dc36e7..001a5e9 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -1820,7 +1820,8 @@ static int fan_init(void)
 	if (sfan_handle) {
 		/* 570, 770x-JL */
 		fan_control_access_mode = IBMACPI_FAN_WR_ACPI_SFAN;
-		fan_control_commands |= IBMACPI_FAN_CMD_LEVEL;
+		fan_control_commands |=
+		    IBMACPI_FAN_CMD_LEVEL | IBMACPI_FAN_CMD_ENABLE;
 	} else {
 		if (!gfan_handle) {
 			/* gfan without sfan means no fan control */
@@ -1980,10 +1981,34 @@ static int fan_set_level(int level)
 
 static int fan_set_enable(void)
 {
+	u8 s;
+	int rc;
+
 	switch (fan_control_access_mode) {
 	case IBMACPI_FAN_WR_ACPI_FANS:
 	case IBMACPI_FAN_WR_TPEC:
-		if (!acpi_ec_write(fan_status_offset, 0x80))
+		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;
+
+		if (!acpi_ec_write(fan_status_offset, s))
+			return -EIO;
+		break;
+
+	case IBMACPI_FAN_WR_ACPI_SFAN:
+		if ((rc = fan_get_status(&s)) < 0)
+			return rc;
+
+		s &= 0x07;
+
+		/* Set fan to at least level 4 */
+		if (s < 4)
+			s = 4;
+
+		if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", s))
 			return -EIO;
 		break;
 
@@ -2002,6 +2027,11 @@ static int fan_set_disable(void)
 			return -EIO;
 		break;
 
+	case IBMACPI_FAN_WR_ACPI_SFAN:
+		if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", 0x00))
+			return -EIO;
+		break;
+
 	default:
 		return -ENXIO;
 	}

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

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

* [PATCH 13/21] ACPI: ibm-acpi: fix and extend fan control functions
  2006-11-25 20:41 [PATCH 00/21] ACPI: ibm-acpi: cleanups, extended fan/thermal support Henrique de Moraes Holschuh
                   ` (3 preceding siblings ...)
  2006-11-25 20:45 ` [PATCH 11/21] ACPI: ibm-acpi: extend fan status functions Henrique de Moraes Holschuh
@ 2006-11-25 20:46 ` Henrique de Moraes Holschuh
  2006-11-25 20:46 ` [PATCH 14/21] ACPI: ibm-acpi: store embedded controller firmware version for matching Henrique de Moraes Holschuh
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-11-25 20:46 UTC (permalink / raw)
  To: len.brown; +Cc: ibm-acpi-devel, linux-acpi

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

This patch extend fan control functions, implementing enable/disable for
all write access modes, implementing level control for all level-capable
write access modes.

The patch also updates the documentation, explaining levels auto and
disengaged.

ABI changes:
	1. Support level 0 as an equivalent to disable
	2. Add support for level auto and level disengaged when doing
	   EC 0x2f fan control
	3. Support enable/disable for all level-based write access modes
	4. Add support for level command on FANS thinkpads, as per
	   thinkwiki reports

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
---

 Documentation/ibm-acpi.txt |   65 +++++++++++++++++++++++++++++++-------------
 drivers/acpi/ibm_acpi.c    |   39 +++++++++++++++++++++++---
 2 files changed, 80 insertions(+), 24 deletions(-)

diff --git a/Documentation/ibm-acpi.txt b/Documentation/ibm-acpi.txt
index 333b8eb..cbd3a60 100644
--- a/Documentation/ibm-acpi.txt
+++ b/Documentation/ibm-acpi.txt
@@ -571,27 +571,57 @@ directly accesses hardware registers and
 WITH CAUTION! To use this feature, you need to supply the
 experimental=1 parameter when loading the module.
 
-This feature attempts to show the current fan speed. 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 value on other models.
+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
+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.
+
+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 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.
+
 WARNING WARNING WARNING: do not leave the fan disabled unless you are
-monitoring the temperature sensor readings and you are ready to enable
-it if necessary to avoid overheating.
+monitoring all of the temperature sensor readings and you are ready to
+enable it if necessary to avoid overheating.
+
+An enabled fan in level "auto" may stop spinning if the EC decides the
+ThinkPad is cool enough and doesn't need the extra airflow.  This is
+normal, and the EC will spin the fan up if the varios thermal readings
+rise too much.
+
+On the X40, this seems to depend on the CPU and HDD temperatures.
+Specifically, the fan is turned on when either the CPU temperature
+climbs to 56 degrees or the HDD temperature climbs to 46 degrees.  The
+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 fan level can be controlled with the command:
 
-The fan only runs if it's enabled *and* the various temperature
-sensors which control it read high enough. On the X40, this seems to
-depend on the CPU and HDD temperatures. Specifically, the fan is
-turned on when either the CPU temperature climbs to 56 degrees or the
-HDD temperature climbs to 46 degrees. The 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.
+	echo 'level <level>' > /proc/acpi/ibm/thermal
+
+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.
 
 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
@@ -604,12 +634,9 @@ about 3700 to about 7350. Values outside
 any effect or the fan speed eventually settles somewhere in that
 range. The fan cannot be stopped or started with this command.
 
-On the 570, temperature readings are not available through this
-feature and the fan control works a little differently. The fan speed
-is reported in levels from 0 (off) to 7 (max) and can be controlled
-with the following command:
-
-	echo 'level <level>' > /proc/acpi/ibm/thermal
+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.
 
 EXPERIMENTAL: WAN -- /proc/acpi/ibm/wan
 ---------------------------------------
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 001a5e9..7ea4a26 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -1833,10 +1833,13 @@ static int fan_init(void)
 				    IBMACPI_FAN_WR_ACPI_FANS;
 				fan_control_commands |=
 				    IBMACPI_FAN_CMD_SPEED |
+				    IBMACPI_FAN_CMD_LEVEL |
 				    IBMACPI_FAN_CMD_ENABLE;
 			} else {
 				fan_control_access_mode = IBMACPI_FAN_WR_TPEC;
-				fan_control_commands |= IBMACPI_FAN_CMD_ENABLE;
+				fan_control_commands |=
+				    IBMACPI_FAN_CMD_LEVEL |
+				    IBMACPI_FAN_CMD_ENABLE;
 			}
 		}
 	}
@@ -1948,9 +1951,20 @@ static int fan_read(char *p)
 		len += sprintf(p + len, "status:\t\tnot supported\n");
 	}
 
-	if (fan_control_commands & IBMACPI_FAN_CMD_LEVEL)
-		len += sprintf(p + len, "commands:\tlevel <level>"
-			       " (<level> is 0-7)\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");
@@ -1973,6 +1987,17 @@ 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) &&
+		    ((level < 0) || (level > 7)))
+			return -EINVAL;
+
+		if (!acpi_ec_write(fan_status_offset, level))
+			return -EIO;
+		break;
+
 	default:
 		return -ENXIO;
 	}
@@ -2060,7 +2085,11 @@ static int fan_write_cmd_level(const cha
 {
 	int level;
 
-	if (sscanf(cmd, "level %d", &level) != 1)
+	if (strlencmp(cmd, "level auto") == 0)
+		level = IBMACPI_FAN_EC_AUTO;
+	else if (strlencmp(cmd, "level disengaged") == 0)
+		level = IBMACPI_FAN_EC_DISENGAGED;
+	else if (sscanf(cmd, "level %d", &level) != 1)
 		return 0;
 
 	if ((*rc = fan_set_level(level)) == -ENXIO)

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

* [PATCH 14/21] ACPI: ibm-acpi: store embedded controller firmware version for matching
  2006-11-25 20:41 [PATCH 00/21] ACPI: ibm-acpi: cleanups, extended fan/thermal support Henrique de Moraes Holschuh
                   ` (4 preceding siblings ...)
  2006-11-25 20:46 ` [PATCH 13/21] ACPI: ibm-acpi: fix and extend fan control functions Henrique de Moraes Holschuh
@ 2006-11-25 20:46 ` Henrique de Moraes Holschuh
  2006-11-25 20:46 ` [PATCH 15/21] ACPI: ibm-acpi: workaround for EC 0x2f initialization bug Henrique de Moraes Holschuh
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-11-25 20:46 UTC (permalink / raw)
  To: len.brown; +Cc: ibm-acpi-devel, linux-acpi

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

This patch changes the ThinkPad Embedded Controller DMI matching
code to store the firmware version of the EC for later usage, e.g.
for quirks.

It also prints the firmware version when starting up.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
---

 drivers/acpi/ibm_acpi.c |   23 ++++++++++++++++++-----
 1 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 7ea4a26..af83977 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -77,6 +77,7 @@
 #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 <asm/uaccess.h>
@@ -361,7 +362,7 @@ enum {					/* Fan control constants */
 						 * control */
 };
 
-static int ibm_thinkpad_ec_found;
+static char* ibm_thinkpad_ec_found = NULL;
 
 struct ibm_struct {
 	char *name;
@@ -2539,11 +2540,15 @@ static void acpi_ibm_exit(void)
 		ibm_exit(&ibms[i]);
 
 	remove_proc_entry(IBM_DIR, acpi_root_dir);
+
+	if (ibm_thinkpad_ec_found)
+		kfree(ibm_thinkpad_ec_found);
 }
 
-static int __init check_dmi_for_ec(void)
+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,
@@ -2553,10 +2558,15 @@ static int __init check_dmi_for_ec(void)
 	 * See http://thinkwiki.org/wiki/List_of_DMI_IDs
 	 */
 	while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
-		if (strstr(dev->name, "IBM ThinkPad Embedded Controller"))
-			return 1;
+		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 0;
+	return NULL;
 }
 
 static int __init acpi_ibm_init(void)
@@ -2580,6 +2590,9 @@ static int __init acpi_ibm_init(void)
 
 	/* Models with newer firmware report the EC in DMI */
 	ibm_thinkpad_ec_found = check_dmi_for_ec();
+	if (ibm_thinkpad_ec_found)
+		printk(IBM_INFO "ThinkPad EC firmware %s\n",
+		       ibm_thinkpad_ec_found);
 
 	/* these handles are not required */
 	IBM_HANDLE_INIT(vid);

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

* [PATCH 15/21] ACPI: ibm-acpi: workaround for EC 0x2f initialization bug
  2006-11-25 20:41 [PATCH 00/21] ACPI: ibm-acpi: cleanups, extended fan/thermal support Henrique de Moraes Holschuh
                   ` (5 preceding siblings ...)
  2006-11-25 20:46 ` [PATCH 14/21] ACPI: ibm-acpi: store embedded controller firmware version for matching Henrique de Moraes Holschuh
@ 2006-11-25 20:46 ` Henrique de Moraes Holschuh
  2006-11-25 20:47 ` [PATCH 17/21] ACPI: ibm-acpi: add support for the ultrabay on the T60,X60 Henrique de Moraes Holschuh
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-11-25 20:46 UTC (permalink / raw)
  To: len.brown; +Cc: ibm-acpi-devel, linux-acpi

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

A few ThinkPads fail to initialize EC register 0x2f both in the EC
firmware and ACPI DSDT.  If the BIOS and the ACPI DSDT also do not
initialize it, then the initial status of that register does not
correspond to reality.

On all reported buggy machines, EC 0x2f will read 0x07 (fan level 7) upon
cold boot, when the EC is actually in mode 0x80 (auto mode).  Since
returning a text string ("unknown") would break a number of userspace
programs, instead we correct the reading for the most probably correct
answer, and return it is in auto mode.

The workaround flags the status and level as unknown on module load/kernel
boot, until we are certain at least one fan control command was issued,
either by us, or by something else.

We don't work around the bug by doing a "fan enable" at module
load/startup (which would initialize the EC register) because it is not
known if these ThinkPad ACPI DSDT might have set the fan to level 7
instead of "auto" (we don't know if they can do this or not) due to a
thermal condition, and we don't want to override that, should they be
capable of it.

We should be setting the workaround flag to "status known" upon resume, as
both reports and a exaustive search on the DSDT tables at acpi.sf.net show
that the DSDTs always enable the fan on resume, thus working around the
bug.  But since we don't have suspend/resume handlers in ibm-acpi yet and
the "EC register 0x2f was modified" logic is likely to catch the change
anyway, we don't.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
---

 drivers/acpi/ibm_acpi.c |   53 +++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index af83977..f742c33 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -362,7 +362,7 @@ enum {					/* Fan control constants */
 						 * control */
 };
 
-static char* ibm_thinkpad_ec_found = NULL;
+static char *ibm_thinkpad_ec_found = NULL;
 
 struct ibm_struct {
 	char *name;
@@ -1794,13 +1794,15 @@ static enum fan_status_access_mode fan_s
 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_init(void)
 {
-	u8 status;
-
 	fan_status_access_mode = IBMACPI_FAN_NONE;
 	fan_control_access_mode = IBMACPI_FAN_WR_NONE;
 	fan_control_commands = 0;
+	fan_control_status_known = 1;
 
 	if (gfan_handle) {
 		/* 570, 600e/x, 770e, 770x */
@@ -1808,8 +1810,33 @@ static int fan_init(void)
 	} else {
 		/* all other ThinkPads: note that even old-style
 		 * ThinkPad ECs supports the fan control register */
-		if (likely(acpi_ec_read(fan_status_offset, &status))) {
+		if (likely(acpi_ec_read(fan_status_offset,
+					&fan_control_initial_status))) {
 			fan_status_access_mode = IBMACPI_FAN_RD_TPEC;
+
+			/* In some ThinkPads, neither the EC nor the ACPI
+			 * DSDT initialize the fan status, and it ends up
+			 * being set to 0x07 when it *could* be either
+			 * 0x07 or 0x80.
+			 *
+			 * Enable for TP-1Y (T43), TP-78 (R51e),
+			 * TP-76 (R52), TP-70 (T43, R52), which are known
+			 * to be buggy. */
+			if (fan_control_initial_status == 0x07 &&
+			    ibm_thinkpad_ec_found &&
+			    ((ibm_thinkpad_ec_found[0] == '1' &&
+			      ibm_thinkpad_ec_found[1] == 'Y') ||
+			     (ibm_thinkpad_ec_found[0] == '7' &&
+			      (ibm_thinkpad_ec_found[1] == '6' ||
+			       ibm_thinkpad_ec_found[1] == '8' ||
+			       ibm_thinkpad_ec_found[1] == '0'))
+			    )) {
+				printk(IBM_NOTICE
+				       "fan_init: initial fan status is "
+				       "unknown, assuming it is in auto "
+				       "mode\n");
+				fan_control_status_known = 0;
+			}
 		} else {
 			printk(IBM_ERR
 			       "ThinkPad ACPI EC access misbehaving, "
@@ -1930,9 +1957,21 @@ static int fan_read(char *p)
 		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;
 
@@ -1997,6 +2036,8 @@ static int fan_set_level(int level)
 
 		if (!acpi_ec_write(fan_status_offset, level))
 			return -EIO;
+		else
+			fan_control_status_known = 1;
 		break;
 
 	default:
@@ -2022,6 +2063,8 @@ static int fan_set_enable(void)
 
 		if (!acpi_ec_write(fan_status_offset, s))
 			return -EIO;
+		else
+			fan_control_status_known = 1;
 		break;
 
 	case IBMACPI_FAN_WR_ACPI_SFAN:
@@ -2051,6 +2094,8 @@ static int fan_set_disable(void)
 	case IBMACPI_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:

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

* [PATCH 16/21] ACPI: ibm-acpi: implement fan watchdog command
       [not found] ` <20061125204155.6604.35338.stgit-H32KNTuDSMjdPi8JTuvWk31TOOPCyuNQ5NbjCUgZEJk@public.gmane.org>
                     ` (7 preceding siblings ...)
  2006-11-25 20:45   ` [PATCH 12/21] ACPI: ibm-acpi: fix and extend fan enable Henrique de Moraes Holschuh
@ 2006-11-25 20:47   ` Henrique de Moraes Holschuh
  2006-11-25 20:47   ` [PATCH 18/21] ACPI: ibm-acpi: make non-generic bay support optional Henrique de Moraes Holschuh
                     ` (3 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-11-25 20:47 UTC (permalink / raw)
  To: len.brown-ral2JQCrhuEAvxtiuMwx3w
  Cc: ibm-acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA

From: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>

This patch implements a fan control safety watchdog, by request of the
authors of userspace fan control scripts.

When the watchdog timer expires, the equivalent action of a "fan enable"
command is executed.  The watchdog timer is reset at every reception of a
fan control command that could change the state of the fan itself.

This command is meant to be used by userspace fan control daemons, to make
sure the fan is never left set to an unsafe level because of userspace
problems.

Users of the X31/X40/X41 "speed" command are on their own, the current
implementation of "speed" is just too incomplete to be used safely,
anyway.  Better to never use it, and just use the "level" command instead.

The watchdog is programmed using echo "watchdog <number>" > fan, where
number is the number of seconds to wait before doing an "enable", and zero
disables the watchdog.

Signed-off-by: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>
---

 Documentation/ibm-acpi.txt |   20 +++++++++++++
 drivers/acpi/ibm_acpi.c    |   70 ++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 87 insertions(+), 3 deletions(-)

diff --git a/Documentation/ibm-acpi.txt b/Documentation/ibm-acpi.txt
index cbd3a60..0132d36 100644
--- a/Documentation/ibm-acpi.txt
+++ b/Documentation/ibm-acpi.txt
@@ -670,6 +670,26 @@ 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
 ---------------------
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index f742c33..adf3dae 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -82,6 +82,8 @@
 #include <linux/backlight.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>
@@ -348,7 +350,8 @@ enum fan_control_access_mode {
 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 */
+	IBMACPI_FAN_CMD_ENABLE	= 0x0004,	/* enable/disable cmd,
+						 * and also watchdog cmd */
 };
 
 enum {					/* Fan control constants */
@@ -1797,12 +1800,17 @@ static enum fan_control_commands fan_con
 static int fan_control_status_known;
 static u8 fan_control_initial_status;
 
+static void fan_watchdog_fire(void *ignored);
+static int fan_watchdog_maxinterval;
+static DECLARE_WORK(fan_watchdog_task, fan_watchdog_fire, NULL);
+
 static int fan_init(void)
 {
 	fan_status_access_mode = IBMACPI_FAN_NONE;
 	fan_control_access_mode = IBMACPI_FAN_WR_NONE;
 	fan_control_commands = 0;
 	fan_control_status_known = 1;
+	fan_watchdog_maxinterval = 0;
 
 	if (gfan_handle) {
 		/* 570, 600e/x, 770e, 770x */
@@ -1934,6 +1942,31 @@ static int fan_get_speed(unsigned int *s
 	return 0;
 }
 
+static void fan_exit(void)
+{
+	cancel_delayed_work(&fan_watchdog_task);
+	flush_scheduled_work();
+}
+
+static void fan_watchdog_reset(void)
+{
+	static int fan_watchdog_active = 0;
+
+	if (fan_watchdog_active)
+		cancel_delayed_work(&fan_watchdog_task);
+
+	if (fan_watchdog_maxinterval > 0) {
+		fan_watchdog_active = 1;
+		if (!schedule_delayed_work(&fan_watchdog_task,
+				msecs_to_jiffies(fan_watchdog_maxinterval
+						 * 1000))) {
+			printk(IBM_ERR "failed to schedule the fan watchdog, "
+			       "watchdog will not trigger\n");
+		}
+	} else
+		fan_watchdog_active = 0;
+}
+
 static int fan_read(char *p)
 {
 	int len = 0;
@@ -2007,7 +2040,9 @@ static int fan_read(char *p)
 	}
 
 	if (fan_control_commands & IBMACPI_FAN_CMD_ENABLE)
-		len += sprintf(p + len, "commands:\tenable, disable\n");
+		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>"
@@ -2186,6 +2221,21 @@ static int fan_write_cmd_speed(const cha
 	return 1;
 }
 
+static int fan_write_cmd_watchdog(const char *cmd, int *rc)
+{
+	int interval;
+
+	if (sscanf(cmd, "watchdog %d", &interval) != 1)
+		return 0;
+
+	if (interval < 0 || interval > 120)
+		*rc = -EINVAL;
+	else
+		fan_watchdog_maxinterval = interval;
+
+	return 1;
+}
+
 static int fan_write(char *buf)
 {
 	char *cmd;
@@ -2196,16 +2246,29 @@ static int fan_write(char *buf)
 		      fan_write_cmd_level(cmd, &rc)) &&
 		    !((fan_control_commands & IBMACPI_FAN_CMD_ENABLE) &&
 		      (fan_write_cmd_enable(cmd, &rc) ||
-		       fan_write_cmd_disable(cmd, &rc))) &&
+		       fan_write_cmd_disable(cmd, &rc) ||
+		       fan_write_cmd_watchdog(cmd, &rc))) &&
 		    !((fan_control_commands & IBMACPI_FAN_CMD_SPEED) &&
 		      fan_write_cmd_speed(cmd, &rc))
 		    )
 			rc = -EINVAL;
+		else if (!rc)
+			fan_watchdog_reset();
 	}
 
 	return rc;
 }
 
+static void fan_watchdog_fire(void *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();
+	}
+}
+
 static struct ibm_struct ibms[] = {
 	{
 	 .name = "driver",
@@ -2317,6 +2380,7 @@ static struct ibm_struct ibms[] = {
 	 .read = fan_read,
 	 .write = fan_write,
 	 .init = fan_init,
+	 .exit = fan_exit,
 	 .experimental = 1,
 	 },
 };

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

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

* [PATCH 17/21] ACPI: ibm-acpi: add support for the ultrabay on the T60,X60
  2006-11-25 20:41 [PATCH 00/21] ACPI: ibm-acpi: cleanups, extended fan/thermal support Henrique de Moraes Holschuh
                   ` (6 preceding siblings ...)
  2006-11-25 20:46 ` [PATCH 15/21] ACPI: ibm-acpi: workaround for EC 0x2f initialization bug Henrique de Moraes Holschuh
@ 2006-11-25 20:47 ` Henrique de Moraes Holschuh
       [not found] ` <20061125204155.6604.35338.stgit-H32KNTuDSMjdPi8JTuvWk31TOOPCyuNQ5NbjCUgZEJk@public.gmane.org>
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-11-25 20:47 UTC (permalink / raw)
  To: len.brown; +Cc: ibm-acpi-devel, linux-acpi

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

This patch adds support for the ultrabay on the T60, X60 and other new
ThinkPads that have a SATA ultrabay.

I intend to keep bay and dock support in ibm-acpi working and updated until
it finally gets deprecated and removed in favour of the generic dock and
bay support.  But we aren't there yet.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
---

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

diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index adf3dae..0151263 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -174,6 +174,7 @@ IBM_HANDLE(dock, root, "\\_SB.GDCK",	/*
 #endif
 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 */
 

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

* [PATCH 18/21] ACPI: ibm-acpi: make non-generic bay support optional
       [not found] ` <20061125204155.6604.35338.stgit-H32KNTuDSMjdPi8JTuvWk31TOOPCyuNQ5NbjCUgZEJk@public.gmane.org>
                     ` (8 preceding siblings ...)
  2006-11-25 20:47   ` [PATCH 16/21] ACPI: ibm-acpi: implement fan watchdog command Henrique de Moraes Holschuh
@ 2006-11-25 20:47   ` Henrique de Moraes Holschuh
  2006-11-25 20:48   ` [PATCH 19/21] ACPI: ibm-acpi: backlight device cleanup Henrique de Moraes Holschuh
                     ` (2 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-11-25 20:47 UTC (permalink / raw)
  To: len.brown-ral2JQCrhuEAvxtiuMwx3w
  Cc: ibm-acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA

From: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>

This patch makes it possible to disable ibm-acpi non-generic bay support,
as generic bay support already works well for a number of ThinkPads.

Signed-off-by: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>
---

 drivers/acpi/Kconfig    |   11 +++++++++++
 drivers/acpi/ibm_acpi.c |   13 ++++++++++++-
 2 files changed, 23 insertions(+), 1 deletions(-)

diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 51745de..440ce9b 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -232,6 +232,17 @@ config ACPI_IBM_DOCK
 
 	  If you are not sure, say N here.
 
+config ACPI_IBM_BAY
+	bool "Legacy Removable Bay Support"
+	depends on ACPI_IBM
+	depends on ACPI_BAY=n
+	default n
+	---help---
+	  Allows the ibm_acpi driver to handle removable bays.
+	  This support is obsoleted by CONFIG_ACPI_BAY.
+
+	  If you are not sure, say N here.
+
 config ACPI_TOSHIBA
 	tristate "Toshiba Laptop Extras"
 	depends on X86
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 0151263..3a4dce1 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -172,6 +172,7 @@ IBM_HANDLE(dock, root, "\\_SB.GDCK",	/*
 	   "\\_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 */ 
@@ -189,6 +190,7 @@ IBM_HANDLE(bay2, root, "\\_SB.PCI0.IDE0.
 IBM_HANDLE(bay2_ej, bay2, "_EJ3",	/* 600e/x, 770e, A3x */
 	   "_EJ0",		/* 770x */
     );				/* all others */
+#endif
 
 /* don't list other alternatives as we install a notify handler on the 570 */
 IBM_HANDLE(pci, root, "\\_SB.PCI");	/* 570 */
@@ -1051,6 +1053,7 @@ 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;
@@ -1060,7 +1063,7 @@ static int _sta(acpi_handle handle)
 
 	return status;
 }
-
+#endif
 #ifdef CONFIG_ACPI_IBM_DOCK
 #define dock_docked() (_sta(dock_handle) & 1)
 
@@ -1126,6 +1129,7 @@ static void dock_notify(struct ibm_struc
 }
 #endif
 
+#ifdef CONFIG_ACPI_IBM_BAY
 static int bay_status_supported;
 static int bay_status2_supported;
 static int bay_eject_supported;
@@ -1201,6 +1205,7 @@ static void bay_notify(struct ibm_struct
 {
 	acpi_bus_generate_event(ibm->device, event, 0);
 }
+#endif
 
 static int cmos_read(char *p)
 {
@@ -2330,6 +2335,7 @@ static struct ibm_struct ibms[] = {
 	 .type = ACPI_SYSTEM_NOTIFY,
 	 },
 #endif
+#ifdef CONFIG_ACPI_IBM_BAY
 	{
 	 .name = "bay",
 	 .init = bay_init,
@@ -2339,6 +2345,7 @@ static struct ibm_struct ibms[] = {
 	 .handle = &bay_handle,
 	 .type = ACPI_SYSTEM_NOTIFY,
 	 },
+#endif
 	{
 	 .name = "cmos",
 	 .read = cmos_read,
@@ -2623,7 +2630,9 @@ IBM_PARAM(light);
 #ifdef CONFIG_ACPI_IBM_DOCK
 IBM_PARAM(dock);
 #endif
+#ifdef CONFIG_ACPI_IBM_BAY
 IBM_PARAM(bay);
+#endif
 IBM_PARAM(cmos);
 IBM_PARAM(led);
 IBM_PARAM(beep);
@@ -2716,12 +2725,14 @@ static int __init acpi_ibm_init(void)
 	IBM_HANDLE_INIT(dock);
 #endif
 	IBM_HANDLE_INIT(pci);
+#ifdef CONFIG_ACPI_IBM_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
 	IBM_HANDLE_INIT(beep);
 	IBM_HANDLE_INIT(ecrd);
 	IBM_HANDLE_INIT(ecwr);

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

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

* [PATCH 19/21] ACPI: ibm-acpi: backlight device cleanup
       [not found] ` <20061125204155.6604.35338.stgit-H32KNTuDSMjdPi8JTuvWk31TOOPCyuNQ5NbjCUgZEJk@public.gmane.org>
                     ` (9 preceding siblings ...)
  2006-11-25 20:47   ` [PATCH 18/21] ACPI: ibm-acpi: make non-generic bay support optional Henrique de Moraes Holschuh
@ 2006-11-25 20:48   ` Henrique de Moraes Holschuh
  2006-11-25 20:48   ` [PATCH 20/21] ACPI: ibm-acpi: style fixes and cruft removal Henrique de Moraes Holschuh
  2006-11-25 20:48   ` [PATCH 21/21] ACPI: ibm-acpi: update version and copyright Henrique de Moraes Holschuh
  12 siblings, 0 replies; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-11-25 20:48 UTC (permalink / raw)
  To: len.brown-ral2JQCrhuEAvxtiuMwx3w
  Cc: ibm-acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA

From: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>

This patch cleans up the recently added backlight device support by Holger
Macht <hmacht-l3A5Bk7waGM@public.gmane.org> to fit well with the rest of the code, using the
ibms struct as the other "subdrivers" in ibm-acpi.

Signed-off-by: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>
---

 drivers/acpi/ibm_acpi.c |   50 +++++++++++++++++++++++++++++------------------
 1 files changed, 31 insertions(+), 19 deletions(-)

diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 3a4dce1..649db29 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -397,7 +397,7 @@ struct ibm_struct {
 
 static struct proc_dir_entry *proc_dir = NULL;
 
-static struct backlight_device *ibm_backlight_device;
+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")
@@ -1639,6 +1639,7 @@ static int brightness_get(struct backlig
 		return -EIO;
 
 	level &= 0x7;
+
 	return level;
 }
 
@@ -1713,6 +1714,33 @@ static int brightness_update_status(stru
 	return brightness_set(bd->props->brightness);
 }
 
+static struct backlight_properties ibm_backlight_data = {
+        .owner          = THIS_MODULE,
+        .get_brightness = brightness_get,
+        .update_status  = brightness_update_status,
+        .max_brightness = 7,
+};
+
+static int brightness_init(void)
+{
+	ibm_backlight_device = backlight_device_register("ibm", 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);
+	}
+
+	return 0;
+}
+
+static void brightness_exit(void)
+{
+	if (ibm_backlight_device) {
+		backlight_device_unregister(ibm_backlight_device);
+		ibm_backlight_device = NULL;
+	}
+}
+
 static int volume_offset = 0x30;
 
 static int volume_read(char *p)
@@ -2377,6 +2405,8 @@ static struct ibm_struct ibms[] = {
 	 .name = "brightness",
 	 .read = brightness_read,
 	 .write = brightness_write,
+	 .init = brightness_init,
+	 .exit = brightness_exit,
 	 },
 	{
 	 .name = "volume",
@@ -2641,20 +2671,10 @@ IBM_PARAM(brightness);
 IBM_PARAM(volume);
 IBM_PARAM(fan);
 
-static struct backlight_properties ibm_backlight_data = {
-	.owner = THIS_MODULE,
-	.get_brightness = brightness_get,
-	.update_status = brightness_update_status,
-	.max_brightness = 7,
-};
-
 static void acpi_ibm_exit(void)
 {
 	int i;
 
-	if (ibm_backlight_device)
-		backlight_device_unregister(ibm_backlight_device);
-
 	for (i = ARRAY_SIZE(ibms) - 1; i >= 0; i--)
 		ibm_exit(&ibms[i]);
 
@@ -2757,14 +2777,6 @@ static int __init acpi_ibm_init(void)
 		}
 	}
 
-	ibm_backlight_device = backlight_device_register("ibm", NULL,
-							 &ibm_backlight_data);
-	if (IS_ERR(ibm_backlight_device)) {
-		printk(IBM_ERR "Could not register ibm backlight device\n");
-		ibm_backlight_device = NULL;
-		acpi_ibm_exit();
-	}
-
 	return 0;
 }
 

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

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

* [PATCH 20/21] ACPI: ibm-acpi: style fixes and cruft removal
       [not found] ` <20061125204155.6604.35338.stgit-H32KNTuDSMjdPi8JTuvWk31TOOPCyuNQ5NbjCUgZEJk@public.gmane.org>
                     ` (10 preceding siblings ...)
  2006-11-25 20:48   ` [PATCH 19/21] ACPI: ibm-acpi: backlight device cleanup Henrique de Moraes Holschuh
@ 2006-11-25 20:48   ` Henrique de Moraes Holschuh
  2006-11-25 20:48   ` [PATCH 21/21] ACPI: ibm-acpi: update version and copyright Henrique de Moraes Holschuh
  12 siblings, 0 replies; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-11-25 20:48 UTC (permalink / raw)
  To: len.brown-ral2JQCrhuEAvxtiuMwx3w
  Cc: ibm-acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA

From: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>

This patch just fixes style, move some #defines to enums, and removes some
old cruft.

Signed-off-by: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>
---

 drivers/acpi/ibm_acpi.c |  100 ++++++++++++++++++++---------------------------
 1 files changed, 43 insertions(+), 57 deletions(-)

diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 649db29..549c834 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -78,9 +78,11 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/string.h>
+
 #include <linux/proc_fs.h>
 #include <linux/backlight.h>
 #include <asm/uaccess.h>
+
 #include <linux/dmi.h>
 #include <linux/jiffies.h>
 #include <linux/workqueue.h>
@@ -121,28 +123,6 @@ static acpi_handle root_handle = NULL;
 	static char        *object##_path;			\
 	static char        *object##_paths[] = { paths }
 
-/*
- * The following models are supported to various degrees:
- *
- * 570, 600e, 600x, 770e, 770x
- * A20m, A21e, A21m, A21p, A22p, A30, A30p, A31, A31p
- * G40, G41
- * R30, R31, R32, R40, R40e, R50, R50e, R50p, R51
- * T20, T21, T22, T23, T30, T40, T40p, T41, T41p, T42, T42p, T43
- * X20, X21, X22, X23, X24, X30, X31, X40
- *
- * The following models have no supported features:
- *
- * 240, 240x, i1400
- *
- * Still missing DSDTs for the following models:
- *
- * A20p, A22e, A22m
- * R52
- * S31
- * T43p
- */
-
 IBM_HANDLE(ec, root, "\\_SB.PCI0.ISA.EC0",	/* 240, 240x */
 	   "\\_SB.PCI.ISA.EC",	/* 570 */
 	   "\\_SB.PCI0.ISA0.EC0",	/* 600e/x, 770e, 770x */
@@ -785,12 +765,15 @@ static int wan_write(char *buf)
 	return 0;
 }
 
-static int video_supported;
-static int video_orig_autosw;
+enum video_access_mode {
+	IBMACPI_VIDEO_NONE = 0,
+	IBMACPI_VIDEO_570,	/* 570 */
+	IBMACPI_VIDEO_770,	/* 600e/x, 770e, 770x */
+	IBMACPI_VIDEO_NEW,	/* all others */
+};
 
-#define VIDEO_570 1
-#define VIDEO_770 2
-#define VIDEO_NEW 3
+static enum video_access_mode video_supported;
+static int video_orig_autosw;
 
 static int video_init(void)
 {
@@ -802,16 +785,16 @@ static int video_init(void)
 
 	if (!vid_handle)
 		/* video switching not supported on R30, R31 */
-		video_supported = 0;
+		video_supported = IBMACPI_VIDEO_NONE;
 	else if (acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd"))
 		/* 570 */
-		video_supported = VIDEO_570;
+		video_supported = IBMACPI_VIDEO_570;
 	else if (acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd"))
 		/* 600e/x, 770e, 770x */
-		video_supported = VIDEO_770;
+		video_supported = IBMACPI_VIDEO_770;
 	else
 		/* all others */
-		video_supported = VIDEO_NEW;
+		video_supported = IBMACPI_VIDEO_NEW;
 
 	return 0;
 }
@@ -821,15 +804,15 @@ static int video_status(void)
 	int status = 0;
 	int i;
 
-	if (video_supported == VIDEO_570) {
+	if (video_supported == IBMACPI_VIDEO_570) {
 		if (acpi_evalf(NULL, &i, "\\_SB.PHS", "dd", 0x87))
 			status = i & 3;
-	} else if (video_supported == VIDEO_770) {
+	} else if (video_supported == IBMACPI_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 == VIDEO_NEW) {
+	} else if (video_supported == IBMACPI_VIDEO_NEW) {
 		acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1);
 		if (acpi_evalf(NULL, &i, "\\VCDC", "d"))
 			status |= 0x02 * i;
@@ -848,9 +831,10 @@ static int video_autosw(void)
 {
 	int autosw = 0;
 
-	if (video_supported == VIDEO_570)
+	if (video_supported == IBMACPI_VIDEO_570)
 		acpi_evalf(vid_handle, &autosw, "SWIT", "d");
-	else if (video_supported == VIDEO_770 || video_supported == VIDEO_NEW)
+	else if (video_supported == IBMACPI_VIDEO_770 ||
+		 video_supported == IBMACPI_VIDEO_NEW)
 		acpi_evalf(vid_handle, &autosw, "^VDEE", "d");
 
 	return autosw & 1;
@@ -870,12 +854,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 == VIDEO_NEW)
+	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 == VIDEO_NEW)
+	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");
@@ -890,7 +874,7 @@ static int video_switch(void)
 
 	if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1))
 		return -EIO;
-	ret = video_supported == VIDEO_570 ?
+	ret = video_supported == IBMACPI_VIDEO_570 ?
 	    acpi_evalf(ec_handle, NULL, "_Q16", "v") :
 	    acpi_evalf(vid_handle, NULL, "VSWT", "v");
 	acpi_evalf(vid_handle, NULL, "_DOS", "vd", autosw);
@@ -900,9 +884,9 @@ static int video_switch(void)
 
 static int video_expand(void)
 {
-	if (video_supported == VIDEO_570)
+	if (video_supported == IBMACPI_VIDEO_570)
 		return acpi_evalf(ec_handle, NULL, "_Q17", "v");
-	else if (video_supported == VIDEO_770)
+	else if (video_supported == IBMACPI_VIDEO_770)
 		return acpi_evalf(vid_handle, NULL, "VEXP", "v");
 	else
 		return acpi_evalf(NULL, NULL, "\\VEXP", "v");
@@ -912,10 +896,10 @@ static int video_switch2(int status)
 {
 	int ret;
 
-	if (video_supported == VIDEO_570) {
+	if (video_supported == IBMACPI_VIDEO_570) {
 		ret = acpi_evalf(NULL, NULL,
 				 "\\_SB.PHS2", "vdd", 0x8b, status | 0x80);
-	} else if (video_supported == VIDEO_770) {
+	} else if (video_supported == IBMACPI_VIDEO_770) {
 		int autosw = video_autosw();
 		if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1))
 			return -EIO;
@@ -951,10 +935,10 @@ static int video_write(char *buf)
 			enable |= 0x02;
 		} else if (strlencmp(cmd, "crt_disable") == 0) {
 			disable |= 0x02;
-		} else if (video_supported == VIDEO_NEW &&
+		} else if (video_supported == IBMACPI_VIDEO_NEW &&
 			   strlencmp(cmd, "dvi_enable") == 0) {
 			enable |= 0x08;
-		} else if (video_supported == VIDEO_NEW &&
+		} else if (video_supported == IBMACPI_VIDEO_NEW &&
 			   strlencmp(cmd, "dvi_disable") == 0) {
 			disable |= 0x08;
 		} else if (strlencmp(cmd, "auto_enable") == 0) {
@@ -1253,26 +1237,28 @@ static int cmos_write(char *buf)
 	return 0;
 }
 
-static int led_supported;
-
-#define LED_570 1
-#define LED_OLD 2
-#define LED_NEW 3
+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)
 {
 	if (!led_handle)
 		/* led not supported on R30, R31 */
-		led_supported = 0;
+		led_supported = IBMACPI_LED_NONE;
 	else if (strlencmp(led_path, "SLED") == 0)
 		/* 570 */
-		led_supported = LED_570;
+		led_supported = IBMACPI_LED_570;
 	else if (strlencmp(led_path, "SYSL") == 0)
 		/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
-		led_supported = LED_OLD;
+		led_supported = IBMACPI_LED_OLD;
 	else
 		/* all others */
-		led_supported = LED_NEW;
+		led_supported = IBMACPI_LED_NEW;
 
 	return 0;
 }
@@ -1289,7 +1275,7 @@ static int led_read(char *p)
 	}
 	len += sprintf(p + len, "status:\t\tsupported\n");
 
-	if (led_supported == LED_570) {
+	if (led_supported == IBMACPI_LED_570) {
 		/* 570 */
 		int i, status;
 		for (i = 0; i < 8; i++) {
@@ -1338,13 +1324,13 @@ static int led_write(char *buf)
 		} else
 			return -EINVAL;
 
-		if (led_supported == LED_570) {
+		if (led_supported == IBMACPI_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 == LED_OLD) {
+		} 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);

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

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

* [PATCH 21/21] ACPI: ibm-acpi: update version and copyright
       [not found] ` <20061125204155.6604.35338.stgit-H32KNTuDSMjdPi8JTuvWk31TOOPCyuNQ5NbjCUgZEJk@public.gmane.org>
                     ` (11 preceding siblings ...)
  2006-11-25 20:48   ` [PATCH 20/21] ACPI: ibm-acpi: style fixes and cruft removal Henrique de Moraes Holschuh
@ 2006-11-25 20:48   ` Henrique de Moraes Holschuh
  12 siblings, 0 replies; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-11-25 20:48 UTC (permalink / raw)
  To: len.brown-ral2JQCrhuEAvxtiuMwx3w
  Cc: ibm-acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA

From: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>

Bump up module version, add myself to copyright and MODULE_AUTHOR.

Signed-off-by: Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>
---

 drivers/acpi/ibm_acpi.c |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 549c834..8137c70 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -3,6 +3,7 @@
  *
  *
  *  Copyright (C) 2004-2005 Borislav Deianov <borislav-iA+eEnwkJgzk1uMJSBkQmQ@public.gmane.org>
+ *  Copyright (C) 2006 Henrique de Moraes Holschuh <hmh-N3TV7GIv+o9fyO9Q7EP/yw@public.gmane.org>
  *
  *  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
@@ -19,10 +20,14 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#define IBM_VERSION "0.12a"
+#define IBM_VERSION "0.13"
 
 /*
  *  Changelog:
+ *
+ *  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
@@ -95,7 +100,7 @@
 #define IBM_FILE "ibm_acpi"
 #define IBM_URL "http://ibm-acpi.sf.net/"
 
-MODULE_AUTHOR("Borislav Deianov");
+MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh");
 MODULE_DESCRIPTION(IBM_DESC);
 MODULE_VERSION(IBM_VERSION);
 MODULE_LICENSE("GPL");

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

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

* Re: [PATCH 01/21] ACPI: ibm-acpi: do not use / in driver names
  2006-11-25 20:42 ` [PATCH 01/21] ACPI: ibm-acpi: do not use / in driver names Henrique de Moraes Holschuh
@ 2006-11-29  9:08   ` Zhang Rui
  0 siblings, 0 replies; 26+ messages in thread
From: Zhang Rui @ 2006-11-29  9:08 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh, len.brown; +Cc: ibm-acpi-devel, linux-acpi@vger

On Sat, 2006-11-25 at 18:42 -0200, Henrique de Moraes Holschuh wrote:
> From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
> 
> ibm-acpi uses sub-device names like ibm/hotkey, which get in the way of
> a sysfs conversion.  Fix it to use ibm_hotkey instead.  Thanks to Zhang
> Rui for noticing this.
> 
> Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
> ---
> 
>  drivers/acpi/ibm_acpi.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
> index 9658253..9baae34 100644
> --- a/drivers/acpi/ibm_acpi.c
> +++ b/drivers/acpi/ibm_acpi.c
> @@ -1854,7 +1854,7 @@ static int __init register_driver(struct
>  	}
>  
>  	memset(ibm->driver, 0, sizeof(struct acpi_driver));
> -	sprintf(ibm->driver->name, "%s/%s", IBM_NAME, ibm->name);
> +	sprintf(ibm->driver->name, "%s_%s", IBM_NAME, ibm->name);
>  	ibm->driver->ids = ibm->hid;
>  	ibm->driver->ops.add = &ibm_device_add;
>  
I think this patch should be added to ACPI sysfs patch series, as it's
critical for ACPI sysfs conversion. We should make sure that the patches
won't break ibm_acpi any longer. :)

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

* Re: [PATCH 00/21] ACPI: ibm-acpi: cleanups, extended fan/thermal support
  2006-11-25 20:41 [PATCH 00/21] ACPI: ibm-acpi: cleanups, extended fan/thermal support Henrique de Moraes Holschuh
                   ` (8 preceding siblings ...)
       [not found] ` <20061125204155.6604.35338.stgit-H32KNTuDSMjdPi8JTuvWk31TOOPCyuNQ5NbjCUgZEJk@public.gmane.org>
@ 2006-12-07  6:23 ` Len Brown
  2006-12-07 19:35   ` Henrique de Moraes Holschuh
  2006-12-16  5:43 ` Len Brown
  10 siblings, 1 reply; 26+ messages in thread
From: Len Brown @ 2006-12-07  6:23 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh; +Cc: ibm-acpi-devel, linux-acpi

On Saturday 25 November 2006 15:41, Henrique de Moraes Holschuh wrote:
> git://repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git for-upstream/acpi-test

Henrique,
FYI, A pull of this branch will take everything included underneath it.
In this case, it will take all the contents of acpi-test that this branch is built upon.

That is fine for testing, but it isn't a path to upstream b/c
not everything in acpi-test is going to get sent up to Linus at the same time as ibm-acpi.

For this batch, I'll just re-parent the series, or re-commit the e-mail patches.
But in the future, if you base your patches directly against some snapshot of Linus' tree
and don't include anything else besides your changes, then I can pull it directly.

Of course you can do both by checking your changes in on a branch off of Linus'
baseline and then merging onto your mirror of acpi-test.  In that event I'd
pull from your branch based on Linus' mirror.

thanks,
-Len

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

* Re: [PATCH 00/21] ACPI: ibm-acpi: cleanups, extended fan/thermal support
  2006-12-07  6:23 ` [PATCH 00/21] ACPI: ibm-acpi: cleanups, extended fan/thermal support Len Brown
@ 2006-12-07 19:35   ` Henrique de Moraes Holschuh
  0 siblings, 0 replies; 26+ messages in thread
From: Henrique de Moraes Holschuh @ 2006-12-07 19:35 UTC (permalink / raw)
  To: Len Brown; +Cc: ibm-acpi-devel, linux-acpi

On Thu, 07 Dec 2006, Len Brown wrote:
> Henrique,
> FYI, A pull of this branch will take everything included underneath it.
> In this case, it will take all the contents of acpi-test that this branch is built upon.
> 
> That is fine for testing, but it isn't a path to upstream b/c
> not everything in acpi-test is going to get sent up to Linus at the same time as ibm-acpi.

I was operating under the false idea that the flow should be ibm-acpi-devel
-> acpi-test -> linus.

> For this batch, I'll just re-parent the series, or re-commit the e-mail patches.

Thanks.

> But in the future, if you base your patches directly against some snapshot of Linus' tree
> and don't include anything else besides your changes, then I can pull it directly.
> Of course you can do both by checking your changes in on a branch off of Linus'
> baseline and then merging onto your mirror of acpi-test.  In that event I'd
> pull from your branch based on Linus' mirror.

Will do.

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh

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

* Re: [PATCH 00/21] ACPI: ibm-acpi: cleanups, extended fan/thermal support
  2006-11-25 20:41 [PATCH 00/21] ACPI: ibm-acpi: cleanups, extended fan/thermal support Henrique de Moraes Holschuh
                   ` (9 preceding siblings ...)
  2006-12-07  6:23 ` [PATCH 00/21] ACPI: ibm-acpi: cleanups, extended fan/thermal support Len Brown
@ 2006-12-16  5:43 ` Len Brown
  10 siblings, 0 replies; 26+ messages in thread
From: Len Brown @ 2006-12-16  5:43 UTC (permalink / raw)
  To: Henrique de Moraes Holschuh; +Cc: ibm-acpi-devel, linux-acpi

applied, with this update to play with Linux-2.6.20-rc1

thanks,
-Len

commit 25c68a33b7b74b37793b1250007e5e21d621a7fc
Author: Len Brown <len.brown@intel.com>
Date:   Fri Dec 8 04:43:41 2006 -0500

    ACPI: ibm_acpi: respond to workqueue update
    
    Signed-off-by: Len Brown <len.brown@intel.com>

diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 92e7b6e..ab18007 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -1825,9 +1825,9 @@ 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(void *ignored);
+static void fan_watchdog_fire(struct work_struct *ignored);
 static int fan_watchdog_maxinterval;
-static DECLARE_WORK(fan_watchdog_task, fan_watchdog_fire, NULL);
+static DECLARE_DELAYED_WORK(fan_watchdog_task, fan_watchdog_fire);
 
 static int fan_init(void)
 {
@@ -2284,7 +2284,7 @@ static int fan_write(char *buf)
 	return rc;
 }
 
-static void fan_watchdog_fire(void *ignored)
+static void fan_watchdog_fire(struct work_struct *ignored)
 {
 	printk(IBM_NOTICE "fan watchdog: enabling fan\n");
 	if (fan_set_enable()) {

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

end of thread, other threads:[~2006-12-16  5:44 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-11-25 20:41 [PATCH 00/21] ACPI: ibm-acpi: cleanups, extended fan/thermal support Henrique de Moraes Holschuh
2006-11-25 20:42 ` [PATCH 01/21] ACPI: ibm-acpi: do not use / in driver names Henrique de Moraes Holschuh
2006-11-29  9:08   ` Zhang Rui
2006-11-25 20:42 ` [PATCH 03/21] ACPI: ibm-acpi: Use a enum to select the thermal sensor reading strategy Henrique de Moraes Holschuh
2006-11-25 20:44 ` [PATCH 09/21] ACPI: ibm-acpi: cleanup fan_write Henrique de Moraes Holschuh
2006-11-25 20:45 ` [PATCH 11/21] ACPI: ibm-acpi: extend fan status functions Henrique de Moraes Holschuh
2006-11-25 20:46 ` [PATCH 13/21] ACPI: ibm-acpi: fix and extend fan control functions Henrique de Moraes Holschuh
2006-11-25 20:46 ` [PATCH 14/21] ACPI: ibm-acpi: store embedded controller firmware version for matching Henrique de Moraes Holschuh
2006-11-25 20:46 ` [PATCH 15/21] ACPI: ibm-acpi: workaround for EC 0x2f initialization bug Henrique de Moraes Holschuh
2006-11-25 20:47 ` [PATCH 17/21] ACPI: ibm-acpi: add support for the ultrabay on the T60,X60 Henrique de Moraes Holschuh
     [not found] ` <20061125204155.6604.35338.stgit-H32KNTuDSMjdPi8JTuvWk31TOOPCyuNQ5NbjCUgZEJk@public.gmane.org>
2006-11-25 20:42   ` [PATCH 02/21] ACPI: ibm-acpi: trivial Lindent cleanups Henrique de Moraes Holschuh
2006-11-25 20:43   ` [PATCH 04/21] ACPI: ibm-acpi: Implement direct-ec-access thermal reading modes for up to 16 sensors Henrique de Moraes Holschuh
2006-11-25 20:43   ` [PATCH 05/21] ACPI: ibm-acpi: document thermal sensor locations for the A31 Henrique de Moraes Holschuh
2006-11-25 20:43   ` [PATCH 06/21] ACPI: ibm-acpi: prepare to cleanup fan_read and fan_write Henrique de Moraes Holschuh
2006-11-25 20:44   ` [PATCH 07/21] ACPI: ibm-acpi: clean up fan_read Henrique de Moraes Holschuh
2006-11-25 20:44   ` [PATCH 08/21] ACPI: ibm-acpi: break fan_read into separate functions Henrique de Moraes Holschuh
2006-11-25 20:45   ` [PATCH 10/21] ACPI: ibm-acpi: document fan control Henrique de Moraes Holschuh
2006-11-25 20:45   ` [PATCH 12/21] ACPI: ibm-acpi: fix and extend fan enable Henrique de Moraes Holschuh
2006-11-25 20:47   ` [PATCH 16/21] ACPI: ibm-acpi: implement fan watchdog command Henrique de Moraes Holschuh
2006-11-25 20:47   ` [PATCH 18/21] ACPI: ibm-acpi: make non-generic bay support optional Henrique de Moraes Holschuh
2006-11-25 20:48   ` [PATCH 19/21] ACPI: ibm-acpi: backlight device cleanup Henrique de Moraes Holschuh
2006-11-25 20:48   ` [PATCH 20/21] ACPI: ibm-acpi: style fixes and cruft removal Henrique de Moraes Holschuh
2006-11-25 20:48   ` [PATCH 21/21] ACPI: ibm-acpi: update version and copyright Henrique de Moraes Holschuh
2006-12-07  6:23 ` [PATCH 00/21] ACPI: ibm-acpi: cleanups, extended fan/thermal support Len Brown
2006-12-07 19:35   ` Henrique de Moraes Holschuh
2006-12-16  5:43 ` Len Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox