aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/s3c24xx/patches-2.6.26/0173-fix-pcf50633-kill-white-splash-of-death-on-suspend.p.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/s3c24xx/patches-2.6.26/0173-fix-pcf50633-kill-white-splash-of-death-on-suspend.p.patch')
-rwxr-xr-xtarget/linux/s3c24xx/patches-2.6.26/0173-fix-pcf50633-kill-white-splash-of-death-on-suspend.p.patch263
1 files changed, 263 insertions, 0 deletions
diff --git a/target/linux/s3c24xx/patches-2.6.26/0173-fix-pcf50633-kill-white-splash-of-death-on-suspend.p.patch b/target/linux/s3c24xx/patches-2.6.26/0173-fix-pcf50633-kill-white-splash-of-death-on-suspend.p.patch
new file mode 100755
index 0000000000..c8de0dab85
--- /dev/null
+++ b/target/linux/s3c24xx/patches-2.6.26/0173-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
+