Re: [PATCH] intel_ips: quieten "power or thermal limit exceeded" messages

Previous thread: Re: [Ksummit-2010-discuss] [PATCH] MAINTAINERS: add U: for URL of todo list, add RCU todo list by Joe Perches on Thursday, August 26, 2010 - 4:30 pm. (1 message)

Next thread: Og dreams of kernels by Greg KH on Thursday, August 26, 2010 - 4:55 pm. (5 messages)
From: Joe Perches
Date: Thursday, August 26, 2010 - 4:33 pm

I think you should instead fix your hardware or maybe change

--

From: Cesar Eduardo Barros
Date: Thursday, August 26, 2010 - 5:11 pm

How can I know if this laptop is broken or not? According to Jesse's 
reply, the BIOS lowered the limit, which could explain why it hits the 
limit more often:

intel ips 0000:00:1f.6: Warning: CPU TDP doesn't match expected value 
(found 25, expected 35)

The thermal throttling seems to be also managed by the BIOS (and there 
are no settings about it on the BIOS setup that I remember):

CPU: Physical Processor ID: 0
CPU: Processor Core ID: 0
mce: CPU supports 9 MCE banks
CPU0: Thermal monitoring handled by SMI
using mwait in idle threads.
[...]
CPU0: Intel(R) Core(TM) i3 CPU       M 330  @ 2.13GHz stepping 02
Booting Node   0, Processors  #1
CPU1: Thermal monitoring handled by SMI
  #2
CPU2: Thermal monitoring handled by SMI
  #3 Ok.
CPU3: Thermal monitoring handled by SMI
Brought up 4 CPUs

And ACPI is of no help, it shows two thermal zones, one always showing 
27 C, the other always showing 0 C (and even though that is below the 
reported thresholds of 55 C and 71 C for the fans, the fan still speeds 
up and down on its own, showing that it is just the reporting that is 
broken).

The fan does slow down to almost nothing (or even off) when idle and 
spins up to a strong hot breeze when compiling the kernel (make -j8), so 
the thermal monitoring on the BIOS seems to be working fine. I would 
expect broken hardware to run the fan on high speed all the time (not 
cooling enough) or low speed all the time (thermal sensor broken).

The coretemp module (which is not autoloaded) seems to be more helpful; 
it shows between 43000 and 45000 for temp1_input on both cores when 
idle, going up to 50000-56000 when lightly loaded (I have not looked at 
it yet while doing a heavy compile).

Is there a way to know if all this is just an oddness of this model, or 
if there is something which is not working quite right?

(All the output above is from 2.6.35.3; I am not running 2.3.36-rc2+ 
right now because it hangs on resume, and I have not yet had the time to 


-- 
Cesar ...
From: Joe Perches
Date: Thursday, August 26, 2010 - 5:41 pm

Perhaps you might try this patch and get a bit more information.

It seems a sensible patch and perhaps should be applied anyway.

Signed-off-by: Joe Perches <joe@perches.com>
---
 drivers/platform/x86/intel_ips.c |   58 +++++++++++++++++++++++++++++--------
 1 files changed, 45 insertions(+), 13 deletions(-)

diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c
index 9024480..73f9ad1 100644
--- a/drivers/platform/x86/intel_ips.c
+++ b/drivers/platform/x86/intel_ips.c
@@ -598,17 +598,36 @@ static bool mcp_exceeded(struct ips_driver *ips)
 {
 	unsigned long flags;
 	bool ret = false;
+	u16 mcp_avg_temp;
+	u16 mcp_temp_limit;
+	u16 mcp_power_limit;
+	u32 cpu_avg_power;
+	u32 mch_avg_power;
 
 	spin_lock_irqsave(&ips->turbo_status_lock, flags);
-	if (ips->mcp_avg_temp > (ips->mcp_temp_limit * 100))
-		ret = true;
-	if (ips->cpu_avg_power + ips->mch_avg_power > ips->mcp_power_limit)
-		ret = true;
+
+	mcp_avg_temp = ips->mcp_avg_temp;
+	mcp_temp_limit = ips->mcp_temp_limit;
+	mcp_power_limit = ips->mcp_power_limit;
+	cpu_avg_power = ips->cpu_avg_power;
+	mch_avg_power = ips->mch_avg_power;
+
 	spin_unlock_irqrestore(&ips->turbo_status_lock, flags);
 
-	if (ret)
+	if ((cpu_avg_power + mch_avg_power) > mcp_power_limit) {
 		dev_info(&ips->dev->dev,
-			 "MCP power or thermal limit exceeded\n");
+			 "MCP power limit %d exceeded: %d\n",
+			 mcp_power_limit,
+			 cpu_avg_power + mch_avg_power);
+		ret = true;
+	}
+	if (mcp_avg_temp > (mcp_temp_limit * 100)) {
+		dev_info(&ips->dev->dev,
+			 "MCP thermal limit %d exceeded: %d\n",
+			 mcp_temp_limit * 100,
+			 mcp_avg_temp);
+		ret = true;
+	}
 
 	return ret;
 }
@@ -623,20 +642,33 @@ static bool mcp_exceeded(struct ips_driver *ips)
 static bool cpu_exceeded(struct ips_driver *ips, int cpu)
 {
 	unsigned long flags;
-	int avg;
 	bool ret = false;
+	int avg;
+	int core_temp_limit;
+	u16 core_power_limit;
+	u32 cpu_avg_power;
 
 ...
From: Cesar Eduardo Barros
Date: Thursday, August 26, 2010 - 6:38 pm

Running with it right now. Unless I missed one, the messages do happen 
exactly every five seconds. Here are the first few lines of the dmesg 
(grepping for 'intel ips'), and it does seem a bit strange:

$ dmesg | fgrep intel\ ips
intel ips 0000:00:1f.6: Warning: CPU TDP doesn't match expected value 
(found 25, expected 35)
intel ips 0000:00:1f.6: PCI INT C -> GSI 18 (level, low) -> IRQ 18
intel ips 0000:00:1f.6: IPS driver initialized, MCP temp limit 65535
intel ips 0000:00:1f.6: MCP power limit 65535 exceeded: 25615533
intel ips 0000:00:1f.6: CPU power limit 8183 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 6276 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 7952 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 7155 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 5928 exceeded: 0
intel ips 0000:00:1f.6: MCP power limit 65535 exceeded: 70848
intel ips 0000:00:1f.6: CPU power limit 6430 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 6474 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 5508 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 6569 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 5250 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 5023 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 6209 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 7276 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 9027 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 7008 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 5478 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 6658 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 5192 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 6347 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 5506 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 4447 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 4462 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 4382 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 4862 exceeded: 0
intel ips 0000:00:1f.6: CPU power limit 5218 ...
From: Joe Perches
Date: Friday, August 27, 2010 - 12:39 am

I added a logging message whenever the turbo limits change
and logging messages for power/temp on MCH for completeness.

Maybe this will show something useful like when/how
CPU power limit gets set to 0.

 drivers/platform/x86/intel_ips.c |  105 +++++++++++++++++++++++++++++++-------
 1 files changed, 87 insertions(+), 18 deletions(-)

diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c
index 9024480..9c65e66 100644
--- a/drivers/platform/x86/intel_ips.c
+++ b/drivers/platform/x86/intel_ips.c
@@ -598,17 +598,36 @@ static bool mcp_exceeded(struct ips_driver *ips)
 {
 	unsigned long flags;
 	bool ret = false;
+	u16 mcp_avg_temp;
+	u16 mcp_temp_limit;
+	u16 mcp_power_limit;
+	u32 cpu_avg_power;
+	u32 mch_avg_power;
 
 	spin_lock_irqsave(&ips->turbo_status_lock, flags);
-	if (ips->mcp_avg_temp > (ips->mcp_temp_limit * 100))
-		ret = true;
-	if (ips->cpu_avg_power + ips->mch_avg_power > ips->mcp_power_limit)
-		ret = true;
+
+	mcp_avg_temp = ips->mcp_avg_temp;
+	mcp_temp_limit = ips->mcp_temp_limit;
+	mcp_power_limit = ips->mcp_power_limit;
+	cpu_avg_power = ips->cpu_avg_power;
+	mch_avg_power = ips->mch_avg_power;
+
 	spin_unlock_irqrestore(&ips->turbo_status_lock, flags);
 
-	if (ret)
+	if ((cpu_avg_power + mch_avg_power) > mcp_power_limit) {
+		dev_info(&ips->dev->dev,
+			 "MCP power limit %u exceeded: cpu:%u + mch:%u\n",
+			 mcp_power_limit,
+			 cpu_avg_power, mch_avg_power);
+		ret = true;
+	}
+	if (mcp_avg_temp > (mcp_temp_limit * 100)) {
 		dev_info(&ips->dev->dev,
-			 "MCP power or thermal limit exceeded\n");
+			 "MCP thermal limit %d exceeded: %d\n",
+			 mcp_temp_limit * 100,
+			 mcp_avg_temp);
+		ret = true;
+	}
 
 	return ret;
 }
@@ -623,20 +642,33 @@ static bool mcp_exceeded(struct ips_driver *ips)
 static bool cpu_exceeded(struct ips_driver *ips, int cpu)
 {
 	unsigned long flags;
-	int avg;
 	bool ret = false;
+	int avg;
+	int core_temp_limit;
+	u16 core_power_limit;
+	u32 cpu_avg_power;
 
 ...
From: Cesar Eduardo Barros
Date: Friday, August 27, 2010 - 4:12 pm

Running with it right now, did not help much:

$ dmesg | fgrep 'intel ips'
intel ips 0000:00:1f.6: Warning: CPU TDP doesn't match expected value 
(found 25, expected 35)
intel ips 0000:00:1f.6: PCI INT C -> GSI 18 (level, low) -> IRQ 18
intel ips 0000:00:1f.6: IPS driver initialized, MCP temp limit 65535
intel ips 0000:00:1f.6: MCP power limit 65535 exceeded: cpu:8058 + 
mch:23392829
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 5675
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 6369
intel ips 0000:00:1f.6: MCP power limit 65535 exceeded: cpu:5095 + mch:65379
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 7387
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 8326
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 5943
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 6428
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 5775
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 7061
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 5153
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 5098
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 5208
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 7500
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 9144
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 6722
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 7156
intel ips 0000:00:1f.6: MCP power limit 65535 exceeded: cpu:5693 + mch:64598
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 5856
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 4209
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 4726
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 5259
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 5212
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 4862
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 5281
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 4235
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 4897
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 5257
intel ips 0000:00:1f.6: MCP power limit ...
From: Joe Perches
Date: Friday, August 27, 2010 - 7:21 pm

I believe all these limits should always have non-zero values.
So I still think you've hardware problems, but I suppose it
could be the driver not reading the right registers or some
such.  It seems odd that the driver never printed a logging
message for either of the polling or irq methods to read the
device cpu and thermal limits.

Jesse or any Intel folk, can you verify or suggest anything
better?

If cpu_power_limit, or any _limit, is not set perhaps changing
the test style to verify limit and adding a printed_once alert
for each 0 value limit.  At least that'd shut up the continuous
logging but at least give a notification message.

if (limit) {
	if (measured_val > limit)
		dev_info(foo)
} else
	dev_alert_once()

Maybe something like this:

 drivers/platform/x86/intel_ips.c |  160 +++++++++++++++++++++++++++++++++-----
 1 files changed, 140 insertions(+), 20 deletions(-)

diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c
index 9024480..10eba04 100644
--- a/drivers/platform/x86/intel_ips.c
+++ b/drivers/platform/x86/intel_ips.c
@@ -598,17 +598,53 @@ static bool mcp_exceeded(struct ips_driver *ips)
 {
 	unsigned long flags;
 	bool ret = false;
+	static bool printed_zero_mcp_power_limit;
+	static bool printed_zero_mcp_temp_limit;
+	u16 mcp_avg_temp;
+	u16 mcp_temp_limit;
+	u16 mcp_power_limit;
+	u32 cpu_avg_power;
+	u32 mch_avg_power;
 
 	spin_lock_irqsave(&ips->turbo_status_lock, flags);
-	if (ips->mcp_avg_temp > (ips->mcp_temp_limit * 100))
-		ret = true;
-	if (ips->cpu_avg_power + ips->mch_avg_power > ips->mcp_power_limit)
-		ret = true;
+
+	mcp_avg_temp = ips->mcp_avg_temp;
+	mcp_temp_limit = ips->mcp_temp_limit;
+	mcp_power_limit = ips->mcp_power_limit;
+	cpu_avg_power = ips->cpu_avg_power;
+	mch_avg_power = ips->mch_avg_power;
+
 	spin_unlock_irqrestore(&ips->turbo_status_lock, flags);
 
-	if (ret)
-		dev_info(&ips->dev->dev,
-			 "MCP power or thermal limit exceeded\n");
+	if (mcp_power_limit) {
+		if ...
From: Cesar Eduardo Barros
Date: Saturday, August 28, 2010 - 3:46 am

Come on, no blaming the BIOS? ;-)

If I read the code with your previous patch correctly, show_turbo_limits 
will never be called if poll_turbo_status is false but no interrupt 
happens. And we know no interrupt happened (at least not with nonzero 
register values), because the interrupt handler does two dev_info() 
right at the beginning. So the limits could still be the ones initially 
set at ips_probe().


Wouldn't it make more sense to do the alert when the limit is set, 
instead of when it is used? Also, it should still treat it as limit 
exceeded (better safe than sorry). Something like:

if (measured_val > limit) {
     if (limit)
         dev_info(...);
     ret = true;
}

-- 
Cesar Eduardo Barros
cesarb@cesarb.net
cesar.barros@gmail.com
--

From: Cesar Eduardo Barros
Date: Saturday, August 28, 2010 - 5:52 am

You seem to have dropped the CC list by accident, adding it back.


Here it is:

intel ips 0000:00:1f.6: Warning: CPU TDP doesn't match expected value 
(found 25, expected 35)
intel ips 0000:00:1f.6: PCI INT C -> GSI 18 (level, low) -> IRQ 18
intel ips 0000:00:1f.6: show_turbo_limits:ips_probe cte:1 gte:1 cpt:0 
mpl:65535 mtl:65535 mpl:65535
intel ips 0000:00:1f.6: IPS driver initialized, MCP temp limit 65535
intel ips 0000:00:1f.6: MCP power limit 65535 exceeded: cpu:8004 + 
mch:25353039
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 4841
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 5283
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 5586
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 6077
intel ips 0000:00:1f.6: MCP power limit 65535 exceeded: cpu:5871 + mch:64538
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 5466
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 8589
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 5744
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 4859
intel ips 0000:00:1f.6: MCP power limit 65535 exceeded: cpu:4834 + mch:62385
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 4874
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 5356
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 6557
intel ips 0000:00:1f.6: MCP power limit 65535 exceeded: cpu:7589 + mch:59343
intel ips 0000:00:1f.6: MCP power limit 65535 exceeded: cpu:5536 + mch:60020
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 6676
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 4401
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 5634
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 4038
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 4700
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 5086
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 4930
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 4697
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 5034
intel ips 0000:00:1f.6: CPU power limit 0 exceeded: 5381
intel ...
From: Cesar Eduardo Barros
Date: Saturday, August 28, 2010 - 6:01 am

It seems I made some mistake when copying and pasting the CC: list, I 
fixed it on this message.

-- 
Cesar Eduardo Barros
cesarb@cesarb.net
cesar.barros@gmail.com
--

From: Joe Perches
Date: Saturday, August 28, 2010 - 6:29 am

So ips->core_power_limit is still 0.

Is it bad bios or driver?

I expect the bios/hw is faulty but fingers are easy to point.

Your choice on how to minimize your current logging problem.

Changing the message level to dev_dbg probably isn't the
right thing to do overall, but it may suit you right now.

Thanks for testing.

--

From: Cesar Eduardo Barros
Date: Saturday, August 28, 2010 - 7:18 am

The solution here probably is not less logging. The best solution IMO 
would be to do some sanity checking when loading the module, and if the 
values do not make sense, print something to the log and return -ENODEV.

I expect that, when it works as it should, the first read while loading 
the module already returns sane values, so a sanity check there should 
not have many false positives. OTOH, it is best to not load the module 
when you think things are strange.

-- 
Cesar Eduardo Barros
cesarb@cesarb.net
cesar.barros@gmail.com
--

From: Henrique de Moraes Holschuh
Date: Saturday, August 28, 2010 - 8:23 am

As long as your sanity checking won't make the module fail to load in the
following scenario:

1. environment temperature control fails, room starts to heat up
2. things go south, server reboots due to exceeded temperature limits
3. OS boots in an overheat situation
4. module refuse to load because it expects to never start in a overheating
   situation.

If the sanity checks will cause (4), then don't add them.  rate-limit the
thermal alarms (issue them only once every T, and only if temperature has
increased more than, say, 5°C from the last alarm).

If a given platform is buggy crap (or just el-cheapo trash that overheats
all the time) to the point that the module is useless, blacklist it by DMI


What good is an alarm module that refuses to load when there is an alarm
condition happening already?

-- 
  "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
--

From: Cesar Eduardo Barros
Date: Saturday, August 28, 2010 - 12:07 pm

I have not read the datasheet (I do not even know if it is available to 
the public; I have not looked), but I would not expect to see a power 
limit of 0 even if the CPU is on fire. Of course, you have to be more 
cautious when validating the current temperature (and even then, if it 


This is not an alarm module; AFAIK it is a module for the feature in 
recent Intel CPU/GPU chips which allow you to overclock it a bit as long 
as the thermal and power limit has not been exceeded:

config INTEL_IPS
	tristate "Intel Intelligent Power Sharing"
	depends on ACPI
	---help---
	  Intel Calpella platforms support dynamic power sharing between the
	  CPU and GPU, maximizing performance in a given TDP.  This driver,
	  along with the CPU frequency and i915 drivers, provides that
	  functionality.  If in doubt, say Y here; it will only load on
	  supported platforms.

If the module is not loaded, it simply will not be able to go above its 
nominal clock, so refusing to load it is not that much of a problem.

-- 
Cesar Eduardo Barros
cesarb@cesarb.net
cesar.barros@gmail.com
--

From: Jesse Barnes
Date: Monday, August 30, 2010 - 9:29 am

On Sat, 28 Aug 2010 16:07:08 -0300

It sounds like either your BIOS values are wrong or the driver isn't
fetching them correctly on your platform.

It's possible that the main issue here is bad thermal limits.  There's
obviously a relationship between power and thermal output, but the
driver tries to monitor both.  However it's up to the BIOS to provide
the driver with accurate thermal limits, as well as accurate power
limits.  The power limits sound reasonable at 25W, thus the
informational output about 35W vs 25W (35W is what the MCP can handle,
but some platforms are designed to handle less, so they clamp it down a
bit).  But the temp limits look all wrong.  I'll see if I can find info
on getting better data into the driver...

Thanks,
-- 
Jesse Barnes, Intel Open Source Technology Center
--

From: Cesar Eduardo Barros
Date: Monday, August 30, 2010 - 2:42 pm

If you need more information from this laptop (dmidecode, ACPI AML, 
etc), just ask.

-- 
Cesar Eduardo Barros
cesarb@cesarb.net
cesar.barros@gmail.com
--

From: Jesse Barnes
Date: Thursday, September 23, 2010 - 1:31 pm

On Fri, 27 Aug 2010 19:21:44 -0700

Yes, we do need something like this.  It turns out the BIOS can
optionally program several of these values, and we need to sanity check
them.  If they're not valid (e.g. a core power limit of 0 or MCP temp
limit of 0xffff) we need to use the default values in the limit structs.

I think the programmed limits are valid if they're nonzero and less
than one of the available default limits.  If they're not valid, we
should just use the default values.  I was thinking something like the
below for MCP, but Joe you may want to just update your patch instead
since it's more complete.

Thanks,
-- 
Jesse Barnes, Intel Open Source Technology Center

diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c
index 9024480..ec72e80 100644
--- a/drivers/platform/x86/intel_ips.c
+++ b/drivers/platform/x86/intel_ips.c
@@ -662,6 +662,17 @@ static bool mch_exceeded(struct ips_driver *ips)
 	return ret;
 }
 
+static void clamp_mcp_temp_limit(struct ips_driver *ips)
+{
+	/*
+	 * BIOS may or may not program an MCP limit.  Clamp it to the
+	 * lowest available value.
+	 */
+	if (ips->mcp_temp_limit < ips->core_temp_limit ||
+	    ips->mcp_temp_limit < ips->mch_temp_limit)
+		ips->mcp_temp_limit = min(ips->core_temp_limit, ips->mch_temp_limit);
+}
+
 /**
  * update_turbo_limits - get various limits & settings from regs
  * @ips: IPS driver struct
@@ -686,6 +697,7 @@ static void update_turbo_limits(struct ips_driver *ips)
 	ips->mcp_temp_limit = thm_readw(THM_PTL);
 	ips->mcp_power_limit = thm_readw(THM_MPPC);
 
+	clamp_mcp_temp_limit(ips);
 	/* Ignore BIOS CPU vs GPU pref */
 }
 
@@ -1155,6 +1167,7 @@ static irqreturn_t ips_irq_handler(int irq, void *arg)
 				STS_PTL_SHIFT;
 			ips->mcp_power_limit = (tc1 & STS_PPL_MASK) >>
 				STS_PPL_SHIFT;
+			clamp_mcp_temp_limit(ips);
 			spin_unlock(&ips->turbo_status_lock);
 
 			thm_writeb(THM_SEC, SEC_ACK);

--

From: Joe Perches
Date: Thursday, September 23, 2010 - 1:47 pm

You have my patch yes?

You can probably integrate and validate it
better than I can with your proposed change.

I don't have any of the hardware to test.
If I can otherwise help somehow, let me know.

cheers, Joe

--

From: Jesse Barnes
Date: Thursday, September 23, 2010 - 1:50 pm

On Thu, 23 Sep 2010 13:47:05 -0700

Ah ok, I'll fix it up and respin then, thanks.

-- 
Jesse Barnes, Intel Open Source Technology Center
--

Previous thread: Re: [Ksummit-2010-discuss] [PATCH] MAINTAINERS: add U: for URL of todo list, add RCU todo list by Joe Perches on Thursday, August 26, 2010 - 4:30 pm. (1 message)

Next thread: Og dreams of kernels by Greg KH on Thursday, August 26, 2010 - 4:55 pm. (5 messages)