diff mbox

[09/13] ACPI: thinkpad-acpi: handle HKEY thermal and battery alarms

Message ID 1231650070-21722-10-git-send-email-hmh@hmh.eng.br (mailing list archive)
State Accepted
Headers show

Commit Message

Henrique de Moraes Holschuh Jan. 11, 2009, 5:01 a.m. UTC
Handle some HKEY events that are actually firmware alarms.  For
now, we do the simple thing: log specific messages to the log and let
the thinkpad-specific event pass to userspace.

In the future, these events will be migrated to generic notifications
and subsystems.

These alarms are NOT available on all ThinkPads.  E.g. the T43 only
issues 0x6011 and 0x6012.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
---
 drivers/platform/x86/thinkpad_acpi.c |   63 +++++++++++++++++++++++++++++++--
 1 files changed, 59 insertions(+), 4 deletions(-)

Comments

Len Brown Jan. 15, 2009, 6:45 p.m. UTC | #1
While useful to a techie, it is hard to imagine that these will
become useful to a generic Linux GUI some day that is used by
regular people.

As thermals on thinkpads are handled by the EC, the question
will become what does the OS (kernel and user) do with these
other than notify...  Presumably the platform specific driver
on Windows knows what to do, or knows what not to do...

I suppose we'll figure out what to do when we see these
actually happen w/ any frequency on test machines --
which quite possibly will never.

Len Brown, Intel Open Source Technology Center

On Sun, 11 Jan 2009, Henrique de Moraes Holschuh wrote:

> Handle some HKEY events that are actually firmware alarms.  For
> now, we do the simple thing: log specific messages to the log and let
> the thinkpad-specific event pass to userspace.
> 
> In the future, these events will be migrated to generic notifications
> and subsystems.
> 
> These alarms are NOT available on all ThinkPads.  E.g. the T43 only
> issues 0x6011 and 0x6012.
> 
> Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
> ---
>  drivers/platform/x86/thinkpad_acpi.c |   63 +++++++++++++++++++++++++++++++--
>  1 files changed, 59 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
> index d833ee6..c4e4b64 100644
> --- a/drivers/platform/x86/thinkpad_acpi.c
> +++ b/drivers/platform/x86/thinkpad_acpi.c
> @@ -174,10 +174,12 @@ enum {
>  
>  /* Debugging */
>  #define TPACPI_LOG TPACPI_FILE ": "
> -#define TPACPI_ERR	   KERN_ERR    TPACPI_LOG
> -#define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG
> -#define TPACPI_INFO   KERN_INFO   TPACPI_LOG
> -#define TPACPI_DEBUG  KERN_DEBUG  TPACPI_LOG
> +#define TPACPI_ALERT	KERN_ALERT  TPACPI_LOG
> +#define TPACPI_CRIT	KERN_CRIT   TPACPI_LOG
> +#define TPACPI_ERR	KERN_ERR    TPACPI_LOG
> +#define TPACPI_NOTICE	KERN_NOTICE TPACPI_LOG
> +#define TPACPI_INFO	KERN_INFO   TPACPI_LOG
> +#define TPACPI_DEBUG	KERN_DEBUG  TPACPI_LOG
>  
>  #define TPACPI_DBG_ALL		0xffff
>  #define TPACPI_DBG_INIT		0x0001
> @@ -2614,6 +2616,15 @@ static bool hotkey_notify_wakeup(const u32 hkey,
>  		*ignore_acpi_ev = true;
>  		break;
>  
> +	case 0x2313: /* Battery on critical low level (S3) */
> +	case 0x2413: /* Battery on critical low level (S4) */
> +		printk(TPACPI_ALERT
> +			"EMERGENCY WAKEUP: battery almost empty\n");
> +		/* how to auto-heal: */
> +		/* 2313: woke up from S3, go to S4/S5 */
> +		/* 2413: woke up from S4, go to S5 */
> +		break;
> +
>  	default:
>  		return false;
>  	}
> @@ -2659,6 +2670,45 @@ static bool hotkey_notify_usrevent(const u32 hkey,
>  	}
>  }
>  
> +static bool hotkey_notify_thermal(const u32 hkey,
> +				 bool *send_acpi_ev,
> +				 bool *ignore_acpi_ev)
> +{
> +	/* 0x6000-0x6FFF: thermal alarms */
> +	*send_acpi_ev = true;
> +	*ignore_acpi_ev = false;
> +
> +	switch (hkey) {
> +	case 0x6011:
> +		printk(TPACPI_CRIT
> +			"THERMAL ALARM: battery is too hot!\n");
> +		/* recommended action: warn user through gui */
> +		return true;
> +	case 0x6012:
> +		printk(TPACPI_ALERT
> +			"THERMAL EMERGENCY: battery is extremely hot!\n");
> +		/* recommended action: immediate sleep/hibernate */
> +		return true;
> +	case 0x6021:
> +		printk(TPACPI_CRIT
> +			"THERMAL ALARM: "
> +			"a sensor reports something is too hot!\n");
> +		/* recommended action: warn user through gui, that */
> +		/* some internal component is too hot */
> +		return true;
> +	case 0x6022:
> +		printk(TPACPI_ALERT
> +			"THERMAL EMERGENCY: "
> +			"a sensor reports something is extremely hot!\n");
> +		/* recommended action: immediate sleep/hibernate */
> +		return true;
> +	default:
> +		printk(TPACPI_ALERT
> +			 "THERMAL ALERT: unknown thermal alarm received\n");
> +		return false;
> +	}
> +}
> +
>  static void hotkey_notify(struct ibm_struct *ibm, u32 event)
>  {
>  	u32 hkey;
> @@ -2731,6 +2781,11 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
>  			known_ev = hotkey_notify_usrevent(hkey, &send_acpi_ev,
>  						 &ignore_acpi_ev);
>  			break;
> +		case 6:
> +			/* 0x6000-0x6FFF: thermal alarms */
> +			known_ev = hotkey_notify_thermal(hkey, &send_acpi_ev,
> +						 &ignore_acpi_ev);
> +			break;
>  		case 7:
>  			/* 0x7000-0x7FFF: misc */
>  			if (tp_features.hotkey_wlsw && hkey == 0x7000) {
> -- 
> 1.5.6.5
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Matthew Garrett Jan. 15, 2009, 7:51 p.m. UTC | #2
On Thu, Jan 15, 2009 at 01:45:19PM -0500, Len Brown wrote:
> While useful to a techie, it is hard to imagine that these will
> become useful to a generic Linux GUI some day that is used by
> regular people.

I think it makes sense to tie them to uevents on the appropriate generic 
devices. Even if most hardware doesn't generate them, the ability to pop 
up a notification telling the user that the firmware thinks their system 
is too hot is useful.
Henrique de Moraes Holschuh Jan. 16, 2009, 3:06 a.m. UTC | #3
On Thu, 15 Jan 2009, Matthew Garrett wrote:
> On Thu, Jan 15, 2009 at 01:45:19PM -0500, Len Brown wrote:
> > While useful to a techie, it is hard to imagine that these will
> > become useful to a generic Linux GUI some day that is used by
> > regular people.
> 
> I think it makes sense to tie them to uevents on the appropriate generic 
> devices. Even if most hardware doesn't generate them, the ability to pop 
> up a notification telling the user that the firmware thinks their system 
> is too hot is useful.

Well, it should actually be useful even without the uevents... as long as
the desktop environments are actually smart enough to notice the kernel
really wants to tell the user something when it outputs CRITICAL, ALERT and
EMERGENCY level messages...

Anyway, I actually asked Lenovo what we should do when we get such alarms.

For the non-critical alarms, they suggest warning the user that he needs to
take IMMEDIATE action (save work and suspend, hibernate or power down).

For the critical alarms, the operating system is to initate an immediate,
forced S3 or S4 suspend.  There is real risk of hardware damage if the
machine is not powered down to S3 or S4 levels within a few seconds (thermal
alarm), or of data loss (power failure imminent).

Since those are two very generic and proper responses to two very generic
and proper alarms, I am all for exporting them over uevents... in a generic
way.  That's why I didn't add thinkpad-acpi-specific uevents for them.
diff mbox

Patch

diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index d833ee6..c4e4b64 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -174,10 +174,12 @@  enum {
 
 /* Debugging */
 #define TPACPI_LOG TPACPI_FILE ": "
-#define TPACPI_ERR	   KERN_ERR    TPACPI_LOG
-#define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG
-#define TPACPI_INFO   KERN_INFO   TPACPI_LOG
-#define TPACPI_DEBUG  KERN_DEBUG  TPACPI_LOG
+#define TPACPI_ALERT	KERN_ALERT  TPACPI_LOG
+#define TPACPI_CRIT	KERN_CRIT   TPACPI_LOG
+#define TPACPI_ERR	KERN_ERR    TPACPI_LOG
+#define TPACPI_NOTICE	KERN_NOTICE TPACPI_LOG
+#define TPACPI_INFO	KERN_INFO   TPACPI_LOG
+#define TPACPI_DEBUG	KERN_DEBUG  TPACPI_LOG
 
 #define TPACPI_DBG_ALL		0xffff
 #define TPACPI_DBG_INIT		0x0001
@@ -2614,6 +2616,15 @@  static bool hotkey_notify_wakeup(const u32 hkey,
 		*ignore_acpi_ev = true;
 		break;
 
+	case 0x2313: /* Battery on critical low level (S3) */
+	case 0x2413: /* Battery on critical low level (S4) */
+		printk(TPACPI_ALERT
+			"EMERGENCY WAKEUP: battery almost empty\n");
+		/* how to auto-heal: */
+		/* 2313: woke up from S3, go to S4/S5 */
+		/* 2413: woke up from S4, go to S5 */
+		break;
+
 	default:
 		return false;
 	}
@@ -2659,6 +2670,45 @@  static bool hotkey_notify_usrevent(const u32 hkey,
 	}
 }
 
+static bool hotkey_notify_thermal(const u32 hkey,
+				 bool *send_acpi_ev,
+				 bool *ignore_acpi_ev)
+{
+	/* 0x6000-0x6FFF: thermal alarms */
+	*send_acpi_ev = true;
+	*ignore_acpi_ev = false;
+
+	switch (hkey) {
+	case 0x6011:
+		printk(TPACPI_CRIT
+			"THERMAL ALARM: battery is too hot!\n");
+		/* recommended action: warn user through gui */
+		return true;
+	case 0x6012:
+		printk(TPACPI_ALERT
+			"THERMAL EMERGENCY: battery is extremely hot!\n");
+		/* recommended action: immediate sleep/hibernate */
+		return true;
+	case 0x6021:
+		printk(TPACPI_CRIT
+			"THERMAL ALARM: "
+			"a sensor reports something is too hot!\n");
+		/* recommended action: warn user through gui, that */
+		/* some internal component is too hot */
+		return true;
+	case 0x6022:
+		printk(TPACPI_ALERT
+			"THERMAL EMERGENCY: "
+			"a sensor reports something is extremely hot!\n");
+		/* recommended action: immediate sleep/hibernate */
+		return true;
+	default:
+		printk(TPACPI_ALERT
+			 "THERMAL ALERT: unknown thermal alarm received\n");
+		return false;
+	}
+}
+
 static void hotkey_notify(struct ibm_struct *ibm, u32 event)
 {
 	u32 hkey;
@@ -2731,6 +2781,11 @@  static void hotkey_notify(struct ibm_struct *ibm, u32 event)
 			known_ev = hotkey_notify_usrevent(hkey, &send_acpi_ev,
 						 &ignore_acpi_ev);
 			break;
+		case 6:
+			/* 0x6000-0x6FFF: thermal alarms */
+			known_ev = hotkey_notify_thermal(hkey, &send_acpi_ev,
+						 &ignore_acpi_ev);
+			break;
 		case 7:
 			/* 0x7000-0x7FFF: misc */
 			if (tp_features.hotkey_wlsw && hkey == 0x7000) {