mirror of https://github.com/hak5/openwrt.git
111 lines
3.6 KiB
Diff
111 lines
3.6 KiB
Diff
From ecb5c96f7da9b081efe3c731a0c7b052c2411536 Mon Sep 17 00:00:00 2001
|
|
From: Andy Green <andy@openmoko.com>
|
|
Date: Wed, 2 Jul 2008 22:39:17 +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 8cb6156..4d92c84 100644
|
|
--- a/drivers/i2c/chips/pcf50633.c
|
|
+++ b/drivers/i2c/chips/pcf50633.c
|
|
@@ -2240,6 +2240,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.5
|
|
|