changed Makefile and profiles, added patches for kernel 2.6.24
[openwrt.git] / target / linux / s3c24xx / patches-2.6.26 / 0156-add-use-pcf50633-resume-callback-jbt6k74.patch.patch
1 From b604d51087159af1a18546bf94e16ac6adf74746 Mon Sep 17 00:00:00 2001
2 From: Andy Green <andy@openmoko.com>
3 Date: Fri, 25 Jul 2008 23:06:11 +0100
4 Subject: [PATCH] add-use-pcf50633-resume-callback-jbt6k74.patch
5
6 Adds the resume callback stuff to glamo, then changes
7 jbt6k74 to no longer use a sleeping workqueue, but to
8 make its resume actions dependent on pcf50633 and
9 glamo resume (for backlight and communication to LCM
10 respectively)
11
12 Signed-off-by: Andy Green <andy@openmoko.com>
13 ---
14  arch/arm/mach-s3c2440/mach-gta02.c |   39 ++++++++++++++++++++-
15  drivers/i2c/chips/pcf50633.c       |   17 +++------
16  drivers/mfd/glamo/glamo-core.c     |   16 ++++++++
17  drivers/mfd/glamo/glamo-core.h     |    3 +-
18  drivers/video/display/jbt6k74.c    |   67 +++++++++++++++++++-----------------
19  include/linux/glamofb.h            |    3 ++
20  include/linux/jbt6k74.h            |    4 ++
21  include/linux/pcf50633.h           |    2 +-
22  include/linux/resume-dependency.h  |   10 +++---
23  9 files changed, 108 insertions(+), 53 deletions(-)
24
25 diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
26 index d7882ea..9ba1036 100644
27 --- a/arch/arm/mach-s3c2440/mach-gta02.c
28 +++ b/arch/arm/mach-s3c2440/mach-gta02.c
29 @@ -88,6 +88,12 @@
30  /* arbitrates which sensor IRQ owns the shared SPI bus */
31  static spinlock_t motion_irq_lock;
32  
33 +/* the dependency of jbt / LCM on pcf50633 resume */
34 +struct resume_dependency resume_dep_jbt_pcf;
35 +/* the dependency of jbt / LCM on glamo resume */
36 +struct resume_dependency resume_dep_jbt_glamo;
37 +
38 +
39  /* define FIQ IPC struct */
40  /*
41   * contains stuff FIQ ISR modifies and normal kernel code can see and use
42 @@ -857,21 +863,50 @@ static struct s3c2410_ts_mach_info gta02_ts_cfg = {
43  
44  /* SPI: LCM control interface attached to Glamo3362 */
45  
46 -void gta02_jbt6k74_reset(int devidx, int level)
47 +static void gta02_jbt6k74_reset(int devidx, int level)
48  {
49         glamo_lcm_reset(level);
50  }
51  
52  /* finally bring up deferred backlight resume now LCM is resumed itself */
53  
54 -void gta02_jbt6k74_resuming(int devidx)
55 +static void gta02_jbt6k74_resuming(int devidx)
56  {
57         pcf50633_backlight_resume(pcf50633_global);
58  }
59  
60 +static int gta02_jbt6k74_all_dependencies_resumed(int devidx)
61 +{
62 +       if (!resume_dep_jbt_pcf.called_flag)
63 +               return 0;
64 +
65 +       if (!resume_dep_jbt_glamo.called_flag)
66 +               return 0;
67 +
68 +       return 1;
69 +}
70 +
71 +/* register jbt resume action to be dependent on pcf50633 and glamo resume */
72 +
73 +static void gta02_jbt6k74_suspending(int devindex, struct spi_device *spi)
74 +{
75 +       void jbt6k74_resume(void *spi); /* little white lies about types */
76 +
77 +       resume_dep_jbt_pcf.callback = jbt6k74_resume;
78 +       resume_dep_jbt_pcf.context = (void *)spi;
79 +       pcf50633_register_resume_dependency(pcf50633_global,
80 +                                                          &resume_dep_jbt_pcf);
81 +       resume_dep_jbt_glamo.callback = jbt6k74_resume;
82 +       resume_dep_jbt_glamo.context = (void *)spi;
83 +       glamo_register_resume_dependency(&resume_dep_jbt_glamo);
84 +}
85 +
86 +
87  const struct jbt6k74_platform_data jbt6k74_pdata = {
88         .reset          = gta02_jbt6k74_reset,
89         .resuming       = gta02_jbt6k74_resuming,
90 +       .suspending     = gta02_jbt6k74_suspending,
91 +       .all_dependencies_resumed = gta02_jbt6k74_all_dependencies_resumed,
92  };
93  
94  static struct spi_board_info gta02_spi_board_info[] = {
95 diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
96 index e477cd7..e5ffeff 100644
97 --- a/drivers/i2c/chips/pcf50633.c
98 +++ b/drivers/i2c/chips/pcf50633.c
99 @@ -1928,7 +1928,7 @@ static int pcf50633_detect(struct i2c_adapter *adapter, int address, int kind)
100  
101         pcf50633_global = data;
102  
103 -       init_resume_dependency_list(data->resume_dependency);
104 +       init_resume_dependency_list(&data->resume_dependency);
105  
106         populate_sysfs_group(data);
107  
108 @@ -2143,11 +2143,11 @@ int pcf50633_report_resumers(struct pcf50633_data *pcf, char *buf)
109   */
110  
111  void pcf50633_register_resume_dependency(struct pcf50633_data *pcf,
112 -                                       struct pcf50633_resume_dependency *dep)
113 +                                       struct resume_dependency *dep)
114  {
115 -       register_resume_dependency(pcf->resume_dependency, dep);
116 +       register_resume_dependency(&pcf->resume_dependency, dep);
117  }
118 -EXPORT_SYMBOL_GPL(pcf50633_register_resume_dep);
119 +EXPORT_SYMBOL_GPL(pcf50633_register_resume_dependency);
120  
121  
122  static int pcf50633_suspend(struct device *dev, pm_message_t state)
123 @@ -2240,9 +2240,6 @@ static int pcf50633_resume(struct device *dev)
124         struct i2c_client *client = to_i2c_client(dev);
125         struct pcf50633_data *pcf = i2c_get_clientdata(client);
126         int i;
127 -       struct list_head *pos, *q;
128 -       struct pcf50633_resume_dependency *dep;
129 -
130  
131         mutex_lock(&pcf->lock);
132  
133 @@ -2270,10 +2267,6 @@ static int pcf50633_resume(struct device *dev)
134                 __reg_write(pcf, PCF50633_REG_LEDOUT, pcf->standby_regs.ledout);
135                 __reg_write(pcf, PCF50633_REG_LEDENA, pcf->standby_regs.ledena);
136                 __reg_write(pcf, PCF50633_REG_LEDDIM, pcf->standby_regs.leddim);
137 -       } else { /* force backlight down, platform will restore later */
138 -               __reg_write(pcf, PCF50633_REG_LEDOUT, 2);
139 -               __reg_write(pcf, PCF50633_REG_LEDENA, 0x20);
140 -               __reg_write(pcf, PCF50633_REG_LEDDIM, 1);
141         }
142  
143         /* FIXME: one big read? */
144 @@ -2287,7 +2280,7 @@ static int pcf50633_resume(struct device *dev)
145  
146         pcf50633_irq(pcf->irq, pcf);
147  
148 -       callback_all_resume_dependencies(pcf->resume_dependency);
149 +       callback_all_resume_dependencies(&pcf->resume_dependency);
150  
151         return 0;
152  }
153 diff --git a/drivers/mfd/glamo/glamo-core.c b/drivers/mfd/glamo/glamo-core.c
154 index a6b977b..445ff24 100644
155 --- a/drivers/mfd/glamo/glamo-core.c
156 +++ b/drivers/mfd/glamo/glamo-core.c
157 @@ -1088,6 +1088,8 @@ static int __init glamo_probe(struct platform_device *pdev)
158                 goto out_free;
159         }
160  
161 +       init_resume_dependency_list(&glamo->resume_dependency);
162 +
163         /* register a number of sibling devices whoise IOMEM resources
164          * are siblings of pdev's IOMEM resource */
165  #if 0
166 @@ -1226,6 +1228,18 @@ static int glamo_remove(struct platform_device *pdev)
167  }
168  
169  #ifdef CONFIG_PM
170 +
171 +/* have to export this because struct glamo_core is opaque */
172 +
173 +void glamo_register_resume_dependency(struct resume_dependency *
174 +                                                             resume_dependency)
175 +{
176 +       register_resume_dependency(&glamo_handle->resume_dependency,
177 +                                                            resume_dependency);
178 +}
179 +EXPORT_SYMBOL_GPL(glamo_register_resume_dependency);
180 +
181 +
182  static int glamo_suspend(struct platform_device *pdev, pm_message_t state)
183  {
184         glamo_power(glamo_handle, GLAMO_POWER_SUSPEND);
185 @@ -1235,6 +1249,8 @@ static int glamo_suspend(struct platform_device *pdev, pm_message_t state)
186  static int glamo_resume(struct platform_device *pdev)
187  {
188         glamo_power(glamo_handle, GLAMO_POWER_ON);
189 +       callback_all_resume_dependencies(&glamo_handle->resume_dependency);
190 +
191         return 0;
192  }
193  #else
194 diff --git a/drivers/mfd/glamo/glamo-core.h b/drivers/mfd/glamo/glamo-core.h
195 index cf89f03..1fee059 100644
196 --- a/drivers/mfd/glamo/glamo-core.h
197 +++ b/drivers/mfd/glamo/glamo-core.h
198 @@ -2,7 +2,7 @@
199  #define __GLAMO_CORE_H
200  
201  #include <asm/system.h>
202 -
203 +#include <linux/resume-dependency.h>
204  
205  /* for the time being, we put the on-screen framebuffer into the lowest
206   * VRAM space.  This should make the code easily compatible with the various
207 @@ -29,6 +29,7 @@ struct glamo_core {
208         u_int16_t type;
209         u_int16_t revision;
210         spinlock_t lock;
211 +       struct resume_dependency resume_dependency;
212  };
213  
214  struct glamo_script {
215 diff --git a/drivers/video/display/jbt6k74.c b/drivers/video/display/jbt6k74.c
216 index 178e2da..8e7bf36 100644
217 --- a/drivers/video/display/jbt6k74.c
218 +++ b/drivers/video/display/jbt6k74.c
219 @@ -27,11 +27,8 @@
220  #include <linux/device.h>
221  #include <linux/platform_device.h>
222  #include <linux/delay.h>
223 -#include <linux/workqueue.h>
224  #include <linux/jbt6k74.h>
225  
226 -#include <linux/spi/spi.h>
227 -
228  enum jbt_register {
229         JBT_REG_SLEEP_IN                = 0x10,
230         JBT_REG_SLEEP_OUT               = 0x11,
231 @@ -116,14 +113,12 @@ struct jbt_info {
232         struct mutex lock;              /* protects tx_buf and reg_cache */
233         u16 tx_buf[8];
234         u16 reg_cache[0xEE];
235 -       struct work_struct work;
236 +       int have_resumed;
237  };
238  
239  #define JBT_COMMAND    0x000
240  #define JBT_DATA       0x100
241  
242 -static void jbt_resume_work(struct work_struct *work);
243 -
244  
245  static int jbt_reg_write_nodata(struct jbt_info *jbt, u8 reg)
246  {
247 @@ -576,8 +571,6 @@ static int __devinit jbt_probe(struct spi_device *spi)
248         if (!jbt)
249                 return -ENOMEM;
250  
251 -       INIT_WORK(&jbt->work, jbt_resume_work);
252 -
253         jbt->spi_dev = spi;
254         jbt->state = JBT_STATE_DEEP_STANDBY;
255         mutex_init(&jbt->lock);
256 @@ -635,27 +628,48 @@ static int jbt_suspend(struct spi_device *spi, pm_message_t state)
257         struct jbt_info *jbt = dev_get_drvdata(&spi->dev);
258         struct jbt6k74_platform_data *jbt6k74_pdata = spi->dev.platform_data;
259  
260 +       /* platform needs to register resume dependencies here */
261 +       if (jbt6k74_pdata->suspending)
262 +               (jbt6k74_pdata->suspending)(0, spi);
263 +
264         /* Save mode for resume */
265         jbt->last_state = jbt->state;
266         jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY);
267  
268 -       (jbt6k74_pdata->reset)(0, 0);
269 +       jbt->have_resumed = 0;
270 +
271 +//     (jbt6k74_pdata->reset)(0, 0);
272  
273         return 0;
274  }
275  
276 -static void jbt_resume_work(struct work_struct *work)
277 +int jbt6k74_resume(struct spi_device *spi)
278  {
279 -       struct jbt_info *jbt = container_of(work, struct jbt_info, work);
280 -       struct jbt6k74_platform_data *jbt6k74_pdata =
281 -                                               jbt->spi_dev->dev.platform_data;
282 +       struct jbt_info *jbt = dev_get_drvdata(&spi->dev);
283 +       struct jbt6k74_platform_data *jbt6k74_pdata = spi->dev.platform_data;
284 +
285 +       /* if we still wait on dependencies, exit because we will get called
286 +        * again.  This guy will get called once by core resume action, and
287 +        * should be set as resume_dependency callback for any dependencies
288 +        * set by platform code.
289 +        */
290  
291 -       printk(KERN_INFO"jbt_resume_work waiting...\n");
292 -       /* 100ms is not enough here 2008-05-08 andy@openmoko.com
293 -        * if CONFIG_PM_DEBUG is enabled 2000ms is required
294 +       if (jbt6k74_pdata->all_dependencies_resumed)
295 +               if (!(jbt6k74_pdata->all_dependencies_resumed)(0))
296 +                       return 0;
297 +
298 +       /* we can get called twice with all dependencies resumed if our core
299 +        * resume callback is last of all.  Protect against going twice
300          */
301 -       msleep(400);
302 -       printk(KERN_INFO"jbt_resume_work GO...\n");
303 +       if (jbt->have_resumed)
304 +               return 0;
305 +
306 +       jbt->have_resumed = 1;
307 +
308 +       /* OK we are sure all devices we depend on for operation are up now */
309 +
310 +       /* even this needs glamo up on GTA02 :-/ */
311 +       (jbt6k74_pdata->reset)(0, 1);
312  
313         jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY);
314         msleep(100);
315 @@ -675,21 +689,10 @@ static void jbt_resume_work(struct work_struct *work)
316         if (jbt6k74_pdata->resuming)
317                 (jbt6k74_pdata->resuming)(0);
318  
319 -       printk(KERN_INFO"jbt_resume_work done...\n");
320 -}
321 -
322 -static int jbt_resume(struct spi_device *spi)
323 -{
324 -       struct jbt_info *jbt = dev_get_drvdata(&spi->dev);
325 -       struct jbt6k74_platform_data *jbt6k74_pdata = spi->dev.platform_data;
326 -
327 -       (jbt6k74_pdata->reset)(0, 1);
328 -
329 -       if (!schedule_work(&jbt->work))
330 -               dev_err(&spi->dev, "Unable to schedule LCM wakeup work\n");
331 -
332         return 0;
333  }
334 +EXPORT_SYMBOL_GPL(jbt6k74_resume);
335 +
336  #else
337  #define jbt_suspend    NULL
338  #define jbt_resume     NULL
339 @@ -704,7 +707,7 @@ static struct spi_driver jbt6k74_driver = {
340         .probe   = jbt_probe,
341         .remove  = __devexit_p(jbt_remove),
342         .suspend = jbt_suspend,
343 -       .resume  = jbt_resume,
344 +       .resume  = jbt6k74_resume,
345  };
346  
347  static int __init jbt_init(void)
348 diff --git a/include/linux/glamofb.h b/include/linux/glamofb.h
349 index 51bf593..bb4ed0a 100644
350 --- a/include/linux/glamofb.h
351 +++ b/include/linux/glamofb.h
352 @@ -2,6 +2,7 @@
353  #define _LINUX_GLAMOFB_H
354  
355  #include <linux/spi/glamo.h>
356 +#include <linux/resume-dependency.h>
357  
358  struct glamofb_val {
359         unsigned int defval;
360 @@ -36,5 +37,7 @@ struct glamofb_platform_data {
361  int glamofb_cmd_mode(struct glamofb_handle *gfb, int on);
362  int glamofb_cmd_write(struct glamofb_handle *gfb, u_int16_t val);
363  void glamo_lcm_reset(int level);
364 +extern void
365 +glamo_register_resume_dependency(struct resume_dependency * resume_dependency);
366  
367  #endif
368 diff --git a/include/linux/jbt6k74.h b/include/linux/jbt6k74.h
369 index 0ac9124..f0eaf39 100644
370 --- a/include/linux/jbt6k74.h
371 +++ b/include/linux/jbt6k74.h
372 @@ -1,9 +1,13 @@
373  #ifndef __JBT6K74_H__
374  #define __JBT6K74_H__
375  
376 +#include <linux/spi/spi.h>
377 +
378  struct jbt6k74_platform_data {
379         void (*reset)(int devindex, int level);
380         void (*resuming)(int devindex); /* called when LCM is resumed */
381 +       void (*suspending)(int devindex, struct spi_device *spi);
382 +       int (*all_dependencies_resumed)(int devindex);
383  };
384  
385  #endif
386 diff --git a/include/linux/pcf50633.h b/include/linux/pcf50633.h
387 index 2bef616..8a75b28 100644
388 --- a/include/linux/pcf50633.h
389 +++ b/include/linux/pcf50633.h
390 @@ -127,7 +127,7 @@ pcf50633_report_resumers(struct pcf50633_data *pcf, char *buf);
391  
392  extern void
393  pcf50633_register_resume_dependency(struct pcf50633_data *pcf,
394 -                                       struct pcf50633_resume_dependency *dep);
395 +                                       struct resume_dependency *dep);
396  
397  
398  #define PCF50633_FEAT_EXTON    0x00000001      /* not yet supported */
399 diff --git a/include/linux/resume-dependency.h b/include/linux/resume-dependency.h
400 index b13aa3e..e0c0f33 100644
401 --- a/include/linux/resume-dependency.h
402 +++ b/include/linux/resume-dependency.h
403 @@ -38,7 +38,7 @@ struct resume_dependency {
404   */
405  
406  #define init_resume_dependency_list(_head) \
407 -       INIT_LIST_HEAD(&_head.list);
408 +       INIT_LIST_HEAD(&(_head)->list);
409  
410  
411  /* if your resume function depends on something else being resumed first, you
412 @@ -48,8 +48,8 @@ struct resume_dependency {
413   */
414  
415  #define register_resume_dependency(_head, _dep) { \
416 -       _dep->called_flag = 0; \
417 -       list_add(&_dep->list, &_head->list); \
418 +       (_dep)->called_flag = 0; \
419 +       list_add(&(_dep)->list, &(_head)->list); \
420  }
421  
422  /* In the resume function that things can be dependent on, at the end you
423 @@ -61,10 +61,10 @@ struct resume_dependency {
424         struct list_head *_pos, *_q; \
425         struct resume_dependency *_dep; \
426  \
427 -       list_for_each_safe(pos, _q, &_head.list) { \
428 +       list_for_each_safe(_pos, _q, &((_head)->list)) { \
429                 _dep = list_entry(_pos, struct resume_dependency, list); \
430                 _dep->called_flag = 1; \
431 -               (_dep->callback)(dep->context); \
432 +               (_dep->callback)(_dep->context); \
433                 list_del(_pos); \
434         } \
435  }
436 -- 
437 1.5.6.3
438