changed Makefile and profiles, added patches for kernel 2.6.24
[openwrt.git] / target / linux / s3c24xx / patches-2.6.24 / 1122-fix-glamofb-cmd-mode-locking.patch.patch
1 From f2cf4e5f204e981a02a0edaccab4ca39f868ac0f Mon Sep 17 00:00:00 2001
2 From: Andy Green <andy@openmoko.com>
3 Date: Sun, 13 Apr 2008 07:25:56 +0100
4 Subject: [PATCH] fix-glamofb-cmd-mode-locking.patch
5
6 Glamo "cmd mode" is modal, but nothing took care about locking.
7 Also cmd mode was entered recursively in rotate_lcd().
8
9 Signed-off-by: Andy Green <andy@openmoko.com>
10 ---
11  drivers/mfd/glamo/glamo-core.c |    2 +-
12  drivers/mfd/glamo/glamo-fb.c   |  106 +++++++++++++++++++++++++--------------
13  include/linux/glamofb.h        |    2 +-
14  3 files changed, 70 insertions(+), 40 deletions(-)
15
16 diff --git a/drivers/mfd/glamo/glamo-core.c b/drivers/mfd/glamo/glamo-core.c
17 index accd933..19ca363 100644
18 --- a/drivers/mfd/glamo/glamo-core.c
19 +++ b/drivers/mfd/glamo/glamo-core.c
20 @@ -588,7 +588,7 @@ int glamo_engine_reclock(struct glamo_core *glamo,
21         if (val) {
22                 val--;
23                 reg_set_bit_mask(glamo, reg, mask, val);
24 -               msleep(5); /* wait some time to stabilize */
25 +               mdelay(5); /* wait some time to stabilize */
26  
27                 return 0;
28         } else {
29 diff --git a/drivers/mfd/glamo/glamo-fb.c b/drivers/mfd/glamo/glamo-fb.c
30 index 87c7420..8633e44 100644
31 --- a/drivers/mfd/glamo/glamo-fb.c
32 +++ b/drivers/mfd/glamo/glamo-fb.c
33 @@ -36,6 +36,7 @@
34  #include <linux/wait.h>
35  #include <linux/platform_device.h>
36  #include <linux/clk.h>
37 +#include <linux/spinlock.h>
38  
39  #include <asm/io.h>
40  #include <asm/uaccess.h>
41 @@ -50,7 +51,7 @@
42  #include "glamo-regs.h"
43  #include "glamo-core.h"
44  
45 -#ifdef DEBUG
46 +#ifndef DEBUG
47  #define GLAMO_LOG(...)
48  #else
49  #define GLAMO_LOG(...) \
50 @@ -72,6 +73,7 @@ struct glamofb_handle {
51         struct glamofb_platform_data *mach_info;
52         char __iomem *cursor_addr;
53         u_int32_t pseudo_pal[16];
54 +       spinlock_t lock_cmd;
55  };
56  
57  /* 'sibling' spi device for lcm init */
58 @@ -237,6 +239,7 @@ static void rotate_lcd(struct glamofb_handle *glamo,
59                         __u32 rotation)
60  {
61         int glamo_rot;
62 +       unsigned long flags;
63  
64         switch (rotation) {
65                 case FB_ROTATE_UR:
66 @@ -255,7 +258,15 @@ static void rotate_lcd(struct glamofb_handle *glamo,
67                         glamo_rot = GLAMO_LCD_ROT_MODE_0;
68                         break;
69         }
70 -       glamofb_cmd_mode(glamo, 1);
71 +
72 +       /*
73 +        * ha ha we are only called when we are in cmd mode already
74 +        * printk(KERN_ERR"rotate_lcd spin_lock_irqsave\n");
75 +        * spin_lock_irqsave(&glamo->lock_cmd, flags);
76 +        *
77 +        * if (glamofb_cmd_mode(glamo, 1))
78 +        *              goto out_unlock;
79 +        */
80         reg_set_bit_mask(glamo,
81                          GLAMO_REG_LCD_WIDTH,
82                          GLAMO_LCD_ROT_MODE_MASK,
83 @@ -265,17 +276,19 @@ static void rotate_lcd(struct glamofb_handle *glamo,
84                          GLAMO_LCD_MODE1_ROTATE_EN,
85                          (glamo_rot != GLAMO_LCD_ROT_MODE_0)?
86                                  GLAMO_LCD_MODE1_ROTATE_EN : 0);
87 -       glamofb_cmd_mode(glamo, 0);
88 +/*     glamofb_cmd_mode(glamo, 0);
89 +
90 +out_unlock:
91 +       printk(KERN_ERR"rotate_lcd spin_unlock_irqrestore\n");
92 +       spin_unlock_irqrestore(&glamo->lock_cmd, flags);
93 +*/
94  }
95  
96  static enum orientation get_orientation(struct fb_var_screeninfo *var)
97  {
98 -       GLAMO_LOG("mark\n")
99 -       if (var->xres <= var->yres) {
100 -               GLAMO_LOG("portrait\n")
101 +       if (var->xres <= var->yres)
102                 return ORIENTATION_PORTRAIT;
103 -       }
104 -       GLAMO_LOG("landscape\n")
105 +
106         return ORIENTATION_LANDSCAPE;
107  }
108  
109 @@ -299,12 +312,18 @@ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo,
110                                           struct fb_var_screeninfo *var)
111  {
112         int sync, bp, disp, fp, total, xres, yres, pitch, orientation_changing;
113 +       unsigned long flags;
114  
115 -       GLAMO_LOG("enter: glamo:%#x, var:%#x\n", (unsigned)glamo, (unsigned)var);
116 +/*     GLAMO_LOG("enter: glamo:%#x, var:%#x\n", (unsigned)glamo, (unsigned)var);
117 +*/
118         if (!glamo || !var)
119                 return;
120  
121 -       glamofb_cmd_mode(glamo, 1);
122 +       printk(KERN_ERR"glamofb_update_lcd_controller spin_lock_irqsave\n");
123 +       spin_lock_irqsave(&glamo->lock_cmd, flags);
124 +
125 +       if (glamofb_cmd_mode(glamo, 1))
126 +               goto out_unlock;
127  
128         if (var->pixclock)
129                 glamo_engine_reclock(glamo->mach_info->glamo,
130 @@ -313,14 +332,14 @@ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo,
131  
132         xres = var->xres;
133         yres = var->yres;
134 -       GLAMO_LOG("xres:%d, yres:%d, rotate:%d\n", xres, yres, var->rotate);
135 -
136 +/*     GLAMO_LOG("xres:%d, yres:%d, rotate:%d\n", xres, yres, var->rotate);
137 +*/
138         /*
139          * figure out if orientation is going to change
140          */
141         orientation_changing = will_orientation_change(var);
142 -       GLAMO_LOG("orientation_changing:%d\n", orientation_changing);
143 -
144 +/*     GLAMO_LOG("orientation_changing:%d\n", orientation_changing);
145 +*/
146          /*
147           * adjust the pitch according to new orientation to come
148           */
149 @@ -329,8 +348,8 @@ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo,
150          } else {
151                 pitch = var->xres * var->bits_per_pixel / 8;
152          }
153 -       GLAMO_LOG("pitch:%d\n", pitch);
154 -
155 +/*     GLAMO_LOG("pitch:%d\n", pitch);
156 +*/
157         /*
158          * set the awaiten LCD geometry
159          */
160 @@ -347,7 +366,7 @@ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo,
161                          GLAMO_LCD_PITCH_MASK,
162                          pitch);
163  
164 -       GLAMO_LOG("mark:\n");
165 +/*     GLAMO_LOG("mark:\n");*/
166         /*
167          * honour the rotation request
168          */
169 @@ -365,7 +384,8 @@ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo,
170                 var->yres_virtual = var->yres = yres;
171         }
172  
173 -       GLAMO_LOG("reported res:(%d,%d)\n", var->xres, var->yres);
174 +/*     GLAMO_LOG("reported res:(%d,%d)\n", var->xres, var->yres);
175 +*/
176         /*
177          * update scannout timings
178          */
179 @@ -386,8 +406,8 @@ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo,
180         reg_set_bit_mask(glamo, GLAMO_REG_LCD_HORIZ_DISP_END,
181                          GLAMO_LCD_HV_RETR_DISP_END_MASK, fp);
182  
183 -       GLAMO_LOG("mark:\n");
184 -
185 +/*     GLAMO_LOG("mark:\n");
186 +*/
187         sync = 0;
188         bp = sync + var->vsync_len;
189         disp = bp + var->upper_margin;
190 @@ -405,10 +425,13 @@ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo,
191         reg_set_bit_mask(glamo, GLAMO_REG_LCD_VERT_DISP_END,
192                          GLAMO_LCD_HV_RETR_DISP_END_MASK, fp);
193  
194 -       GLAMO_LOG("mark:\n");
195 +/*     GLAMO_LOG("mark:\n"); */
196         glamofb_cmd_mode(glamo, 0);
197  
198 -       GLAMO_LOG("leave:\n");
199 +/*     GLAMO_LOG("leave:\n"); */
200 +out_unlock:
201 +       printk(KERN_ERR"glamofb_update_lcd_controller spin_unlock_irqrestore\n");
202 +       spin_unlock_irqrestore(&glamo->lock_cmd, flags);
203  }
204  
205  static int glamofb_set_par(struct fb_info *info)
206 @@ -552,23 +575,25 @@ static inline int glamofb_cmdq_empty(struct glamofb_handle *gfb)
207         return reg_read(gfb, GLAMO_REG_LCD_STATUS1) & (1 << 15);
208  }
209  
210 -void glamofb_cmd_mode(struct glamofb_handle *gfb, int on)
211 +/* call holding gfb->lock_cmd  when locking, until you unlock */
212 +
213 +int glamofb_cmd_mode(struct glamofb_handle *gfb, int on)
214  {
215 -       int timeout = 20000;
216 +       int timeout = 200000;
217  
218 -       dev_dbg(gfb->dev, "glamofb_cmd_mode(gfb=%p, on=%d)\n", gfb, on);
219 +/*     dev_dbg(gfb->dev, "glamofb_cmd_mode(gfb=%p, on=%d)\n", gfb, on); */
220         if (on) {
221 -               dev_dbg(gfb->dev, "%s: waiting for cmdq empty: ",
222 -                       __FUNCTION__);
223 +/*             dev_dbg(gfb->dev, "%s: waiting for cmdq empty: ",
224 +                       __FUNCTION__); */
225                 while ((!glamofb_cmdq_empty(gfb)) && (timeout--))
226                         yield();
227                 if (timeout < 0) {
228                         printk(KERN_ERR"*************"
229                                        "glamofb cmd_queue never got empty"
230                                        "*************\n");
231 -                       return;
232 +                       return -EIO;
233                 }
234 -               dev_dbg(gfb->dev, "empty!\n");
235 +/*             dev_dbg(gfb->dev, "empty!\n"); */
236  
237                 /* display the entire frame then switch to command */
238                 reg_write(gfb, GLAMO_REG_LCD_COMMAND1,
239 @@ -576,8 +601,8 @@ void glamofb_cmd_mode(struct glamofb_handle *gfb, int on)
240                           GLAMO_LCD_CMD_DATA_FIRE_VSYNC);
241  
242                 /* wait until LCD is idle */
243 -               dev_dbg(gfb->dev, "waiting for LCD idle: ");
244 -               timeout = 2000;
245 +/*             dev_dbg(gfb->dev, "waiting for LCD idle: "); */
246 +               timeout = 200000;
247                 while ((!reg_read(gfb, GLAMO_REG_LCD_STATUS2) & (1 << 12)) &&
248                       (timeout--))
249                         yield();
250 @@ -585,11 +610,11 @@ void glamofb_cmd_mode(struct glamofb_handle *gfb, int on)
251                         printk(KERN_ERR"*************"
252                                        "glamofb lcd never idle"
253                                        "*************\n");
254 -                       return;
255 +                       return -EIO;
256                 }
257 -               dev_dbg(gfb->dev, "idle!\n");
258 +/*             dev_dbg(gfb->dev, "idle!\n"); */
259  
260 -               msleep(90);
261 +               mdelay(100);
262         } else {
263                 /* RGB interface needs vsync/hsync */
264                 if (reg_read(gfb, GLAMO_REG_LCD_MODE3) & GLAMO_LCD_MODE3_RGB)
265 @@ -601,15 +626,17 @@ void glamofb_cmd_mode(struct glamofb_handle *gfb, int on)
266                           GLAMO_LCD_CMD_TYPE_DISP |
267                           GLAMO_LCD_CMD_DATA_DISP_FIRE);
268         }
269 +
270 +       return 0;
271  }
272  EXPORT_SYMBOL_GPL(glamofb_cmd_mode);
273  
274  int glamofb_cmd_write(struct glamofb_handle *gfb, u_int16_t val)
275  {
276 -       int timeout = 20000;
277 +       int timeout = 200000;
278  
279 -       dev_dbg(gfb->dev, "%s: waiting for cmdq empty\n",
280 -               __FUNCTION__);
281 +/*     dev_dbg(gfb->dev, "%s: waiting for cmdq empty\n",
282 +               __FUNCTION__); */
283         while ((!glamofb_cmdq_empty(gfb)) && (timeout--))
284                 yield();
285         if (timeout < 0) {
286 @@ -618,7 +645,7 @@ int glamofb_cmd_write(struct glamofb_handle *gfb, u_int16_t val)
287                                 "*************\n");
288                 return 1;
289         }
290 -       dev_dbg(gfb->dev, "idle, writing 0x%04x\n", val);
291 +/*     dev_dbg(gfb->dev, "idle, writing 0x%04x\n", val); */
292  
293         reg_write(gfb, GLAMO_REG_LCD_COMMAND1, val);
294  
295 @@ -758,6 +785,9 @@ static int __init glamofb_probe(struct platform_device *pdev)
296  
297         glamo_engine_enable(mach_info->glamo, GLAMO_ENGINE_LCD);
298         glamo_engine_reset(mach_info->glamo, GLAMO_ENGINE_LCD);
299 +
300 +       printk(KERN_ERR"spin_lock_init\n");
301 +       spin_lock_init(&glamofb->lock_cmd);
302         glamofb_init_regs(glamofb);
303  
304         rc = register_framebuffer(fbinfo);
305 diff --git a/include/linux/glamofb.h b/include/linux/glamofb.h
306 index 75eefef..51bf593 100644
307 --- a/include/linux/glamofb.h
308 +++ b/include/linux/glamofb.h
309 @@ -33,7 +33,7 @@ struct glamofb_platform_data {
310         int             (*glamo_irq_is_wired)(void);
311  };
312  
313 -void glamofb_cmd_mode(struct glamofb_handle *gfb, int on);
314 +int glamofb_cmd_mode(struct glamofb_handle *gfb, int on);
315  int glamofb_cmd_write(struct glamofb_handle *gfb, u_int16_t val);
316  void glamo_lcm_reset(int level);
317  
318 -- 
319 1.5.6.5
320