diff options
Diffstat (limited to 'target/linux/s3c24xx/patches-2.6.26/1173-fix-pcf50633-kill-white-splash-of-death-on-suspend.p.patch')
-rwxr-xr-x | target/linux/s3c24xx/patches-2.6.26/1173-fix-pcf50633-kill-white-splash-of-death-on-suspend.p.patch | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/target/linux/s3c24xx/patches-2.6.26/1173-fix-pcf50633-kill-white-splash-of-death-on-suspend.p.patch b/target/linux/s3c24xx/patches-2.6.26/1173-fix-pcf50633-kill-white-splash-of-death-on-suspend.p.patch new file mode 100755 index 0000000..c8de0da --- /dev/null +++ b/target/linux/s3c24xx/patches-2.6.26/1173-fix-pcf50633-kill-white-splash-of-death-on-suspend.p.patch @@ -0,0 +1,263 @@ +From df0a2db3e96b39e9cd48acb069f2e60919be49f9 Mon Sep 17 00:00:00 2001 +From: Andy Green <andy@openmoko.com> +Date: Fri, 25 Jul 2008 23:06:14 +0100 +Subject: [PATCH] fix-pcf50633-kill-white-splash-of-death-on-suspend.patch + +mach-gta02 meddles with the regulator platform struct after +it is defined, leading to LCM power getting lost in suspend +despite I set it to be left up. Fixing this finally removes +the incredibly stubborn white LCM on suspend "flash". + +This is also going to be implicated in Sean McNeil's +experience of monochromatic LCM after resume, which was +previously attacked by resetting and re-initing the LCM +from scratch. + +In addition, I realized that we take down core_1v3 in +pcf50633 suspend action, this is happening near the +start of suspend, so we are in a meta-race to finish +suspend in a controlled way before the caps on core_1v3 +run out (I only saw 23.3uF total). If it's true, this +is where the weirdo sensitivity to timing during +suspend is coming from. + +Therefore in this patch we also remove sleeps and +dev_info() etc (which have to flush on serial console) +from the pc50633 isr workqueue if we are in pcf50633 +driver suspend state 1, ie, suspending... because we +don't have time for it. + +Signed-off-by: Andy Green <andy@openmoko.com> +--- + arch/arm/mach-s3c2440/mach-gta02.c | 43 ++++++++++++++++++++++++++---------- + drivers/i2c/chips/pcf50633.c | 29 ++++++++++++----------- + drivers/mfd/glamo/glamo-core.c | 2 + + drivers/video/display/jbt6k74.c | 1 + + 4 files changed, 49 insertions(+), 26 deletions(-) + +diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c +index 654dc8f..0bacafa 100644 +--- a/arch/arm/mach-s3c2440/mach-gta02.c ++++ b/arch/arm/mach-s3c2440/mach-gta02.c +@@ -485,6 +485,9 @@ static struct pcf50633_platform_data gta02_pcf_pdata = { + [1] = PCF50633_INT2_ONKEYF, + [2] = PCF50633_INT3_ONKEY1S + }, ++ /* warning: these get rewritten during machine init below ++ * depending on pcb variant ++ */ + .rails = { + [PCF50633_REGULATOR_AUTO] = { + .name = "io_3v3", +@@ -496,6 +499,12 @@ static struct pcf50633_platform_data gta02_pcf_pdata = { + }, + [PCF50633_REGULATOR_DOWN1] = { + .name = "core_1v3", ++ /* Wow, when we are going into suspend, after pcf50633 ++ * runs its suspend (which happens real early since it ++ * is an i2c device) we are running out of the 22uF cap ++ * on core_1v3 rail !!!! ++ */ ++ .flags = PMU_VRAIL_F_SUSPEND_ON, + .voltage = { + .init = 1300, + .max = 1600, +@@ -503,6 +512,7 @@ static struct pcf50633_platform_data gta02_pcf_pdata = { + }, + [PCF50633_REGULATOR_DOWN2] = { + .name = "core_1v8", ++ .flags = PMU_VRAIL_F_SUSPEND_ON, + .voltage = { + .init = 1800, + .max = 1800, +@@ -516,8 +526,7 @@ static struct pcf50633_platform_data gta02_pcf_pdata = { + }, + }, + [PCF50633_REGULATOR_LDO1] = { +- .name = "stby_1v3", +- .flags = PMU_VRAIL_F_SUSPEND_ON, ++ .name = "gsensor_3v3", + .voltage = { + .init = 1300, + .max = 1330, +@@ -531,7 +540,7 @@ static struct pcf50633_platform_data gta02_pcf_pdata = { + }, + }, + [PCF50633_REGULATOR_LDO3] = { +- .name = "lcm_3v", ++ .name = "unused3", + .voltage = { + .init = 3000, + .max = 3000, +@@ -545,20 +554,28 @@ static struct pcf50633_platform_data gta02_pcf_pdata = { + }, + }, + [PCF50633_REGULATOR_LDO5] = { +- .name = "gl_1v5", ++ .name = "rf3v", + .voltage = { + .init = 1500, + .max = 1500, + }, + }, + [PCF50633_REGULATOR_LDO6] = { +- .name = "user1", ++ .name = "lcm_3v", + .flags = PMU_VRAIL_F_SUSPEND_ON, + .voltage = { + .init = 0, + .max = 3300, + }, + }, ++ [PCF50633_REGULATOR_MEMLDO] = { ++ .name = "memldo", ++ .flags = PMU_VRAIL_F_SUSPEND_ON, ++ .voltage = { ++ .init = 1800, ++ .max = 1800, ++ }, ++ }, + }, + .defer_resume_backlight = 1, + }; +@@ -611,13 +628,15 @@ static void mangle_pmu_pdata_by_system_rev(void) + .max = 3000, + } + }); +- gta02_pcf_pdata.rails[PCF50633_REGULATOR_LDO6] = ((struct pmu_voltage_rail) { +- .name = "lcm_3v", +- .voltage = { +- .init = 3000, +- .max = 3000, +- } +- }); ++ gta02_pcf_pdata.rails[PCF50633_REGULATOR_LDO6] = ++ ((struct pmu_voltage_rail) { ++ .name = "lcm_3v", ++ .flags = PMU_VRAIL_F_SUSPEND_ON, ++ .voltage = { ++ .init = 3000, ++ .max = 3000, ++ } ++ }); + break; + default: + break; +diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c +index 4002c03..37dfca6 100644 +--- a/drivers/i2c/chips/pcf50633.c ++++ b/drivers/i2c/chips/pcf50633.c +@@ -750,9 +750,6 @@ static void pcf50633_work(struct work_struct *work) + mutex_lock(&pcf->working_lock); + pcf->working = 1; + +- dev_info(&pcf->client.dev, "pcf50633_work called with suspended = %d\n", +- pcf->have_been_suspended); +- + /* + * If we are inside suspend -> resume completion time we don't attempt + * service until we have fully resumed. Although we could talk to the +@@ -763,11 +760,8 @@ static void pcf50633_work(struct work_struct *work) + * completed. + */ + +- if (pcf->have_been_suspended && (pcf->have_been_suspended < 3)) { +- dev_info(&pcf->client.dev, "rescheduling, suspended = %d\n", +- pcf->have_been_suspended); ++ if (pcf->have_been_suspended && (pcf->have_been_suspended < 3)) + goto reschedule; +- } + + /* + * datasheet says we have to read the five IRQ +@@ -1157,9 +1151,13 @@ static void pcf50633_work(struct work_struct *work) + + reschedule: + /* don't spew, delaying whatever else is happening */ +- msleep(100); +- +- dev_info(&pcf->client.dev, "rescheduling interrupt service\n"); ++ /* EXCEPTION: if we are in the middle of suspending, we don't have ++ * time to hang around since we may be turned off core 1V3 already ++ */ ++ if (pcf->have_been_suspended != 1) { ++ msleep(50); ++ dev_info(&pcf->client.dev, "rescheduling interrupt service\n"); ++ } + if (!schedule_work(&pcf->work)) + dev_err(&pcf->client.dev, "int service reschedule failed\n"); + +@@ -2333,7 +2331,7 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state) + PCF50633_REG_AUTOOUT, + sizeof(pcf->standby_regs.misc), + &pcf->standby_regs.misc[0]); +- if (ret != 18) ++ if (ret != sizeof(pcf->standby_regs.misc)) + dev_err(dev, "Failed to save misc levels and enables :-(\n"); + + /* regulator voltages and enable states */ +@@ -2341,7 +2339,7 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state) + PCF50633_REG_LDO1OUT, + sizeof(pcf->standby_regs.ldo), + &pcf->standby_regs.ldo[0]); +- if (ret != 14) ++ if (ret != sizeof(pcf->standby_regs.ldo)) + dev_err(dev, "Failed to save LDO levels and enables :-(\n"); + + /* switch off power supplies that are not needed during suspend */ +@@ -2349,8 +2347,6 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state) + if ((pcf->pdata->rails[i].flags & PMU_VRAIL_F_SUSPEND_ON)) + continue; + +- dev_dbg(dev, "disabling regulator %u\n", i); +- + /* we can save ourselves the read part of a read-modify-write + * here because we captured all these already + */ +@@ -2359,6 +2355,11 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state) + else + tmp = pcf->standby_regs.ldo[(i - 4) * 2 + 1]; + ++ dev_info(dev, "disabling reg %s by setting ENA %d to 0x%02X\n", ++ pcf->pdata->rails[i].name, ++ regulator_registers[i] + 1, tmp & 0xfe); ++ ++ /* associated enable is always +1 from OUT reg */ + __reg_write(pcf, regulator_registers[i] + 1, tmp & 0xfe); + } + +diff --git a/drivers/mfd/glamo/glamo-core.c b/drivers/mfd/glamo/glamo-core.c +index 3edbfa8..d4b526d 100644 +--- a/drivers/mfd/glamo/glamo-core.c ++++ b/drivers/mfd/glamo/glamo-core.c +@@ -848,6 +848,7 @@ static void glamo_power(struct glamo_core *glamo, + ARRAY_SIZE(glamo_resume_script), 0); + + break; ++ + case GLAMO_POWER_STANDBY: + /* enable memory self-refresh */ + __reg_set_bit_mask(glamo, GLAMO_REG_MEM_DRAM1, +@@ -859,6 +860,7 @@ static void glamo_power(struct glamo_core *glamo, + __reg_set_bit_mask(glamo, GLAMO_REG_PLL_GEN3, 0x2000, 0xffff); + __reg_set_bit_mask(glamo, GLAMO_REG_DFT_GEN5, 0x0001, 0xffff); + break; ++ + case GLAMO_POWER_SUSPEND: + __reg_set_bit_mask(glamo, GLAMO_REG_MEM_DRAM2, + GLAMO_MEM_DRAM2_DEEP_PWRDOWN, 0xffff); +diff --git a/drivers/video/display/jbt6k74.c b/drivers/video/display/jbt6k74.c +index 6fa1fe7..b406298 100644 +--- a/drivers/video/display/jbt6k74.c ++++ b/drivers/video/display/jbt6k74.c +@@ -634,6 +634,7 @@ static int jbt_suspend(struct spi_device *spi, pm_message_t state) + + /* Save mode for resume */ + jbt->last_state = jbt->state; ++ + jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY); + + jbt->have_resumed = 0; +-- +1.5.6.3 + |