aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-s3c2440/mach-gta02.c17
-rw-r--r--drivers/i2c/chips/pcf50633.c14
-rw-r--r--include/linux/pcf50633.h5
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 22de1819475..5980ea9110e 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 c148ea7191e..82ee2f0bf16 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 8a75b28606f..0522d922fcc 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