diff options
author | Andy Green <andy@openmoko.com> | 2008-11-19 17:09:46 +0000 |
---|---|---|
committer | Andy Green <agreen@pads.home.warmcat.com> | 2008-11-19 17:09:46 +0000 |
commit | 2204d8b104b812411a39118ffb436dfbd479787a (patch) | |
tree | c44cf815b492a2b81717947a4836a264692bb440 /drivers | |
parent | d4f8c947ca4693e5a08c252bcd2f0bb6d1e99592 (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.c | 17 | ||||
-rw-r--r-- | drivers/mfd/glamo/glamo-core.c | 16 | ||||
-rw-r--r-- | drivers/mfd/glamo/glamo-core.h | 3 | ||||
-rw-r--r-- | drivers/video/display/jbt6k74.c | 67 |
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) |