diff options
-rw-r--r-- | arch/arm/mach-s3c2440/mach-gta02.c | 17 | ||||
-rw-r--r-- | drivers/i2c/chips/pcf50633.c | 14 | ||||
-rw-r--r-- | 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 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 |