aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/s3c24xx/patches/0160-fix-glamo-mci-relationship-with-pcf50633-suspend-res.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/s3c24xx/patches/0160-fix-glamo-mci-relationship-with-pcf50633-suspend-res.patch')
-rwxr-xr-xtarget/linux/s3c24xx/patches/0160-fix-glamo-mci-relationship-with-pcf50633-suspend-res.patch110
1 files changed, 110 insertions, 0 deletions
diff --git a/target/linux/s3c24xx/patches/0160-fix-glamo-mci-relationship-with-pcf50633-suspend-res.patch b/target/linux/s3c24xx/patches/0160-fix-glamo-mci-relationship-with-pcf50633-suspend-res.patch
new file mode 100755
index 0000000000..91831933ec
--- /dev/null
+++ b/target/linux/s3c24xx/patches/0160-fix-glamo-mci-relationship-with-pcf50633-suspend-res.patch
@@ -0,0 +1,110 @@
+From 7af35792e1165cb9258e192ddfcb03393eb76f86 Mon Sep 17 00:00:00 2001
+From: Andy Green <andy@openmoko.com>
+Date: Fri, 25 Jul 2008 23:06:12 +0100
+Subject: [PATCH] fix-glamo-mci-relationship-with-pcf50633-suspend-resume.patch
+
+After protecting pcf50633 read and write primitives against
+operation after suspend or before resume (by blowing a
+stack_trace()) I saw glamo-mci was trying to use pcf50633
+at these bad times on its own suspend and resume. Since that
+part was already done via platform callback, I added an
+export in pcf50633 that tells you if it is ready or busy,
+and used it to defer (resume power on case) or ignore
+(suspend power off case, since pcf50633 already did it)
+the mci power call.
+
+Signed-off-by: Andy Green <andy@openmoko.com>
+---
+ arch/arm/mach-s3c2440/mach-gta02.c | 17 ++++++++++-------
+ drivers/i2c/chips/pcf50633.c | 14 ++++++++++++++
+ include/linux/pcf50633.h | 5 +++++
+ 3 files changed, 29 insertions(+), 7 deletions(-)
+
+diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
+index 22de181..5980ea9 100644
+--- a/arch/arm/mach-s3c2440/mach-gta02.c
++++ b/arch/arm/mach-s3c2440/mach-gta02.c
+@@ -1277,13 +1277,12 @@ gta02_glamo_mmc_set_power(unsigned char power_mode, unsigned short vdd)
+ case GTA02v4_SYSTEM_REV:
+ case GTA02v5_SYSTEM_REV:
+ case GTA02v6_SYSTEM_REV:
+- /* depend on pcf50633 driver init */
+- if (!pcf50633_global)
+- while (!pcf50633_global)
+- msleep(10);
+ switch (power_mode) {
+ case MMC_POWER_ON:
+ case MMC_POWER_UP:
++ /* depend on pcf50633 driver init + not suspended */
++ while (pcf50633_ready(pcf50633_global))
++ msleep(1);
+ /* select and set the voltage */
+ if (vdd > 7) {
+ mv += 300 + 100 * (vdd - 8);
+@@ -1292,15 +1291,19 @@ gta02_glamo_mmc_set_power(unsigned char power_mode, unsigned short vdd)
+ }
+ pcf50633_voltage_set(pcf50633_global,
+ PCF50633_REGULATOR_HCLDO, mv);
+- msleep(10);
+ pcf50633_onoff_set(pcf50633_global,
+ PCF50633_REGULATOR_HCLDO, 1);
+- msleep(1);
+ break;
+ case MMC_POWER_OFF:
++ /* power off happens during suspend, when pcf50633 can
++ * be already gone and not coming back... just forget
++ * the action then because pcf50633 suspend already
++ * dealt with it, otherwise we spin forever
++ */
++ if (pcf50633_ready(pcf50633_global))
++ return;
+ pcf50633_onoff_set(pcf50633_global,
+ PCF50633_REGULATOR_HCLDO, 0);
+- msleep(1);
+ break;
+ }
+ break;
+diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
+index c148ea7..82ee2f0 100644
+--- a/drivers/i2c/chips/pcf50633.c
++++ b/drivers/i2c/chips/pcf50633.c
+@@ -2230,6 +2230,20 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state)
+ return 0;
+ }
+
++
++int pcf50633_ready(struct pcf50633_data *pcf)
++{
++ if (!pcf)
++ return -EBUSY;
++
++ if (pcf->have_been_suspended)
++ return -EBUSY;
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(pcf50633_ready);
++
++
+ /*
+ * if backlight resume is selected to be deferred by platform, then it
+ * can call this to finally reset backlight status (after LCM is resumed
+diff --git a/include/linux/pcf50633.h b/include/linux/pcf50633.h
+index 8a75b28..0522d92 100644
+--- a/include/linux/pcf50633.h
++++ b/include/linux/pcf50633.h
+@@ -129,6 +129,11 @@ extern void
+ pcf50633_register_resume_dependency(struct pcf50633_data *pcf,
+ struct resume_dependency *dep);
+
++/* 0 = initialized and resumed and ready to roll, !=0 = either not
++ * initialized or not resumed yet
++ */
++extern int
++pcf50633_ready(struct pcf50633_data *pcf);
+
+ #define PCF50633_FEAT_EXTON 0x00000001 /* not yet supported */
+ #define PCF50633_FEAT_MBC 0x00000002
+--
+1.5.6.3
+