aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorAndy Green <andy@openmoko.com>2008-11-19 17:09:46 +0000
committerAndy Green <agreen@pads.home.warmcat.com>2008-11-19 17:09:46 +0000
commit2204d8b104b812411a39118ffb436dfbd479787a (patch)
treec44cf815b492a2b81717947a4836a264692bb440 /drivers
parentd4f8c947ca4693e5a08c252bcd2f0bb6d1e99592 (diff)
add-use-pcf50633-resume-callback-jbt6k74.patch
Adds the resume callback stuff to glamo, then changes jbt6k74 to no longer use a sleeping workqueue, but to make its resume actions dependent on pcf50633 and glamo resume (for backlight and communication to LCM respectively) Signed-off-by: Andy Green <andy@openmoko.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/i2c/chips/pcf50633.c17
-rw-r--r--drivers/mfd/glamo/glamo-core.c16
-rw-r--r--drivers/mfd/glamo/glamo-core.h3
-rw-r--r--drivers/video/display/jbt6k74.c67
4 files changed, 58 insertions, 45 deletions
diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
index e477cd7fa32..e5ffeff711d 100644
--- a/drivers/i2c/chips/pcf50633.c
+++ b/drivers/i2c/chips/pcf50633.c
@@ -1928,7 +1928,7 @@ static int pcf50633_detect(struct i2c_adapter *adapter, int address, int kind)
pcf50633_global = data;
- init_resume_dependency_list(data->resume_dependency);
+ init_resume_dependency_list(&data->resume_dependency);
populate_sysfs_group(data);
@@ -2143,11 +2143,11 @@ int pcf50633_report_resumers(struct pcf50633_data *pcf, char *buf)
*/
void pcf50633_register_resume_dependency(struct pcf50633_data *pcf,
- struct pcf50633_resume_dependency *dep)
+ struct resume_dependency *dep)
{
- register_resume_dependency(pcf->resume_dependency, dep);
+ register_resume_dependency(&pcf->resume_dependency, dep);
}
-EXPORT_SYMBOL_GPL(pcf50633_register_resume_dep);
+EXPORT_SYMBOL_GPL(pcf50633_register_resume_dependency);
static int pcf50633_suspend(struct device *dev, pm_message_t state)
@@ -2240,9 +2240,6 @@ static int pcf50633_resume(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct pcf50633_data *pcf = i2c_get_clientdata(client);
int i;
- struct list_head *pos, *q;
- struct pcf50633_resume_dependency *dep;
-
mutex_lock(&pcf->lock);
@@ -2270,10 +2267,6 @@ static int pcf50633_resume(struct device *dev)
__reg_write(pcf, PCF50633_REG_LEDOUT, pcf->standby_regs.ledout);
__reg_write(pcf, PCF50633_REG_LEDENA, pcf->standby_regs.ledena);
__reg_write(pcf, PCF50633_REG_LEDDIM, pcf->standby_regs.leddim);
- } else { /* force backlight down, platform will restore later */
- __reg_write(pcf, PCF50633_REG_LEDOUT, 2);
- __reg_write(pcf, PCF50633_REG_LEDENA, 0x20);
- __reg_write(pcf, PCF50633_REG_LEDDIM, 1);
}
/* FIXME: one big read? */
@@ -2287,7 +2280,7 @@ static int pcf50633_resume(struct device *dev)
pcf50633_irq(pcf->irq, pcf);
- callback_all_resume_dependencies(pcf->resume_dependency);
+ callback_all_resume_dependencies(&pcf->resume_dependency);
return 0;
}
diff --git a/drivers/mfd/glamo/glamo-core.c b/drivers/mfd/glamo/glamo-core.c
index a6b977b41f6..445ff242d5b 100644
--- a/drivers/mfd/glamo/glamo-core.c
+++ b/drivers/mfd/glamo/glamo-core.c
@@ -1088,6 +1088,8 @@ static int __init glamo_probe(struct platform_device *pdev)
goto out_free;
}
+ init_resume_dependency_list(&glamo->resume_dependency);
+
/* register a number of sibling devices whoise IOMEM resources
* are siblings of pdev's IOMEM resource */
#if 0
@@ -1226,6 +1228,18 @@ static int glamo_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM
+
+/* have to export this because struct glamo_core is opaque */
+
+void glamo_register_resume_dependency(struct resume_dependency *
+ resume_dependency)
+{
+ register_resume_dependency(&glamo_handle->resume_dependency,
+ resume_dependency);
+}
+EXPORT_SYMBOL_GPL(glamo_register_resume_dependency);
+
+
static int glamo_suspend(struct platform_device *pdev, pm_message_t state)
{
glamo_power(glamo_handle, GLAMO_POWER_SUSPEND);
@@ -1235,6 +1249,8 @@ static int glamo_suspend(struct platform_device *pdev, pm_message_t state)
static int glamo_resume(struct platform_device *pdev)
{
glamo_power(glamo_handle, GLAMO_POWER_ON);
+ callback_all_resume_dependencies(&glamo_handle->resume_dependency);
+
return 0;
}
#else
diff --git a/drivers/mfd/glamo/glamo-core.h b/drivers/mfd/glamo/glamo-core.h
index cf89f032500..1fee05997d6 100644
--- a/drivers/mfd/glamo/glamo-core.h
+++ b/drivers/mfd/glamo/glamo-core.h
@@ -2,7 +2,7 @@
#define __GLAMO_CORE_H
#include <asm/system.h>
-
+#include <linux/resume-dependency.h>
/* for the time being, we put the on-screen framebuffer into the lowest
* VRAM space. This should make the code easily compatible with the various
@@ -29,6 +29,7 @@ struct glamo_core {
u_int16_t type;
u_int16_t revision;
spinlock_t lock;
+ struct resume_dependency resume_dependency;
};
struct glamo_script {
diff --git a/drivers/video/display/jbt6k74.c b/drivers/video/display/jbt6k74.c
index 178e2daba63..8e7bf36f91d 100644
--- a/drivers/video/display/jbt6k74.c
+++ b/drivers/video/display/jbt6k74.c
@@ -27,11 +27,8 @@
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
-#include <linux/workqueue.h>
#include <linux/jbt6k74.h>
-#include <linux/spi/spi.h>
-
enum jbt_register {
JBT_REG_SLEEP_IN = 0x10,
JBT_REG_SLEEP_OUT = 0x11,
@@ -116,14 +113,12 @@ struct jbt_info {
struct mutex lock; /* protects tx_buf and reg_cache */
u16 tx_buf[8];
u16 reg_cache[0xEE];
- struct work_struct work;
+ int have_resumed;
};
#define JBT_COMMAND 0x000
#define JBT_DATA 0x100
-static void jbt_resume_work(struct work_struct *work);
-
static int jbt_reg_write_nodata(struct jbt_info *jbt, u8 reg)
{
@@ -576,8 +571,6 @@ static int __devinit jbt_probe(struct spi_device *spi)
if (!jbt)
return -ENOMEM;
- INIT_WORK(&jbt->work, jbt_resume_work);
-
jbt->spi_dev = spi;
jbt->state = JBT_STATE_DEEP_STANDBY;
mutex_init(&jbt->lock);
@@ -635,27 +628,48 @@ static int jbt_suspend(struct spi_device *spi, pm_message_t state)
struct jbt_info *jbt = dev_get_drvdata(&spi->dev);
struct jbt6k74_platform_data *jbt6k74_pdata = spi->dev.platform_data;
+ /* platform needs to register resume dependencies here */
+ if (jbt6k74_pdata->suspending)
+ (jbt6k74_pdata->suspending)(0, spi);
+
/* Save mode for resume */
jbt->last_state = jbt->state;
jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY);
- (jbt6k74_pdata->reset)(0, 0);
+ jbt->have_resumed = 0;
+
+// (jbt6k74_pdata->reset)(0, 0);
return 0;
}
-static void jbt_resume_work(struct work_struct *work)
+int jbt6k74_resume(struct spi_device *spi)
{
- struct jbt_info *jbt = container_of(work, struct jbt_info, work);
- struct jbt6k74_platform_data *jbt6k74_pdata =
- jbt->spi_dev->dev.platform_data;
+ struct jbt_info *jbt = dev_get_drvdata(&spi->dev);
+ struct jbt6k74_platform_data *jbt6k74_pdata = spi->dev.platform_data;
+
+ /* if we still wait on dependencies, exit because we will get called
+ * again. This guy will get called once by core resume action, and
+ * should be set as resume_dependency callback for any dependencies
+ * set by platform code.
+ */
- printk(KERN_INFO"jbt_resume_work waiting...\n");
- /* 100ms is not enough here 2008-05-08 andy@openmoko.com
- * if CONFIG_PM_DEBUG is enabled 2000ms is required
+ if (jbt6k74_pdata->all_dependencies_resumed)
+ if (!(jbt6k74_pdata->all_dependencies_resumed)(0))
+ return 0;
+
+ /* we can get called twice with all dependencies resumed if our core
+ * resume callback is last of all. Protect against going twice
*/
- msleep(400);
- printk(KERN_INFO"jbt_resume_work GO...\n");
+ if (jbt->have_resumed)
+ return 0;
+
+ jbt->have_resumed = 1;
+
+ /* OK we are sure all devices we depend on for operation are up now */
+
+ /* even this needs glamo up on GTA02 :-/ */
+ (jbt6k74_pdata->reset)(0, 1);
jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY);
msleep(100);
@@ -675,21 +689,10 @@ static void jbt_resume_work(struct work_struct *work)
if (jbt6k74_pdata->resuming)
(jbt6k74_pdata->resuming)(0);
- printk(KERN_INFO"jbt_resume_work done...\n");
-}
-
-static int jbt_resume(struct spi_device *spi)
-{
- struct jbt_info *jbt = dev_get_drvdata(&spi->dev);
- struct jbt6k74_platform_data *jbt6k74_pdata = spi->dev.platform_data;
-
- (jbt6k74_pdata->reset)(0, 1);
-
- if (!schedule_work(&jbt->work))
- dev_err(&spi->dev, "Unable to schedule LCM wakeup work\n");
-
return 0;
}
+EXPORT_SYMBOL_GPL(jbt6k74_resume);
+
#else
#define jbt_suspend NULL
#define jbt_resume NULL
@@ -704,7 +707,7 @@ static struct spi_driver jbt6k74_driver = {
.probe = jbt_probe,
.remove = __devexit_p(jbt_remove),
.suspend = jbt_suspend,
- .resume = jbt_resume,
+ .resume = jbt6k74_resume,
};
static int __init jbt_init(void)