Subject: Powerbook shuts down hard when hot, patch found

From: Michael Buesch <[email-masked]>
Date: Fri, 28 Sep 2007 23:32:52 +0200

Hi,

some time ago I already mailed you about this problem.
I will quickly describe what's going on, again:

My powerbook boots fine when it's cold. You can work with
it and you can also run it hot (compile something, etc...).
But when you try to boot it while it is hot, it will
automatically shutdown hard inside of the boot process.
Some part of the hardware is shutting it down.
This does not happen when it's getting hot _after_ boot.
Only while boot when it's hot.

I bisected the problem and found out that the following patch
is responsible for this. Yeah, this sounds a little bit
crazy, as this patch does not seem to be related to
this at all. But I confirmed it by booting kernel
4f71c5de19c27f2198105d3b26b398494d5c353b
That kernel triggered the bug. Then I patch -R the patch below
and it booted properly, even when hot. I also rechecked
that it really was hot enough to trigger the event by
immediately rebooting into a known bad kernel, that immediately
shut down the pbook, as expected.
So I'm pretty sure it's the patch below causing this weird
behaviour. Any idea why?

commit 4f71c5de19c27f2198105d3b26b398494d5c353b
Author: Benjamin Herrenschmidt <[email-masked]>
Date:   Fri Nov 17 15:35:00 2006 +1100

    [PATCH] Fix radeon DDC regression
    
    When radeonfb was changed to use the new "generic" ddc, a bit of
    code initializing the GPIO lines was lost, causing it to not work
    if the firmware didn't configure them properly, which seems to
    happen on some cards.
    
    Signed-off-by: Benjamin Herrenschmidt <[email-masked]>
    Signed-off-by: Linus Torvalds <[email-masked]>

diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c
index 6767545..869725a 100644
--- a/drivers/video/aty/radeon_i2c.c
+++ b/drivers/video/aty/radeon_i2c.c
@@ -139,7 +139,13 @@ void radeon_delete_i2c_busses(struct rad
 int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn,
 			       u8 **out_edid)
 {
-	u8 *edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter);
+	u32 reg = rinfo->i2c[conn-1].ddc_reg;
+	u8 *edid;
+
+	OUTREG(reg, INREG(reg) &
+			~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT));
+
+	edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter);
 
 	if (out_edid)
 		*out_edid = edid;

-- 
Greetings Michael.