disable IMQ on 2.6.28 as well -- people should use IFB..
[openwrt.git] / target / linux / s3c24xx / patches / 0173-fix-pcf50633-kill-white-splash-of-death-on-suspend.p.patch
1 From df0a2db3e96b39e9cd48acb069f2e60919be49f9 Mon Sep 17 00:00:00 2001
2 From: Andy Green <andy@openmoko.com>
3 Date: Fri, 25 Jul 2008 23:06:14 +0100
4 Subject: [PATCH] fix-pcf50633-kill-white-splash-of-death-on-suspend.patch
5
6 mach-gta02 meddles with the regulator platform struct after
7 it is defined, leading to LCM power getting lost in suspend
8 despite I set it to be left up.  Fixing this finally removes
9 the incredibly stubborn white LCM on suspend "flash".
10
11 This is also going to be implicated in Sean McNeil's
12 experience of monochromatic LCM after resume, which was
13 previously attacked by resetting and re-initing the LCM
14 from scratch.
15
16 In addition, I realized that we take down core_1v3 in
17 pcf50633 suspend action, this is happening near the
18 start of suspend, so we are in a meta-race to finish
19 suspend in a controlled way before the caps on core_1v3
20 run out (I only saw 23.3uF total).  If it's true, this
21 is where the weirdo sensitivity to timing during
22 suspend is coming from.
23
24 Therefore in this patch we also remove sleeps and
25 dev_info() etc (which have to flush on serial console)
26 from the pc50633 isr workqueue if we are in pcf50633
27 driver suspend state 1, ie, suspending... because we
28 don't have time for it.
29
30 Signed-off-by: Andy Green <andy@openmoko.com>
31 ---
32  arch/arm/mach-s3c2440/mach-gta02.c |   43 ++++++++++++++++++++++++++----------
33  drivers/i2c/chips/pcf50633.c       |   29 ++++++++++++-----------
34  drivers/mfd/glamo/glamo-core.c     |    2 +
35  drivers/video/display/jbt6k74.c    |    1 +
36  4 files changed, 49 insertions(+), 26 deletions(-)
37
38 diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
39 index 654dc8f..0bacafa 100644
40 --- a/arch/arm/mach-s3c2440/mach-gta02.c
41 +++ b/arch/arm/mach-s3c2440/mach-gta02.c
42 @@ -485,6 +485,9 @@ static struct pcf50633_platform_data gta02_pcf_pdata = {
43                 [1] = PCF50633_INT2_ONKEYF,
44                 [2] = PCF50633_INT3_ONKEY1S
45         },
46 +       /* warning: these get rewritten during machine init below
47 +        * depending on pcb variant
48 +        */
49         .rails  = {
50                 [PCF50633_REGULATOR_AUTO] = {
51                         .name           = "io_3v3",
52 @@ -496,6 +499,12 @@ static struct pcf50633_platform_data gta02_pcf_pdata = {
53                 },
54                 [PCF50633_REGULATOR_DOWN1] = {
55                         .name           = "core_1v3",
56 +                       /* Wow, when we are going into suspend, after pcf50633
57 +                        * runs its suspend (which happens real early since it
58 +                        * is an i2c device) we are running out of the 22uF cap
59 +                        * on core_1v3 rail !!!!
60 +                        */
61 +                       .flags          = PMU_VRAIL_F_SUSPEND_ON,
62                         .voltage        = {
63                                 .init   = 1300,
64                                 .max    = 1600,
65 @@ -503,6 +512,7 @@ static struct pcf50633_platform_data gta02_pcf_pdata = {
66                 },
67                 [PCF50633_REGULATOR_DOWN2] = {
68                         .name           = "core_1v8",
69 +                       .flags          = PMU_VRAIL_F_SUSPEND_ON,
70                         .voltage        = {
71                                 .init   = 1800,
72                                 .max    = 1800,
73 @@ -516,8 +526,7 @@ static struct pcf50633_platform_data gta02_pcf_pdata = {
74                         },
75                 },
76                 [PCF50633_REGULATOR_LDO1] = {
77 -                       .name           = "stby_1v3",
78 -                       .flags          = PMU_VRAIL_F_SUSPEND_ON,
79 +                       .name           = "gsensor_3v3",
80                         .voltage        = {
81                                 .init   = 1300,
82                                 .max    = 1330,
83 @@ -531,7 +540,7 @@ static struct pcf50633_platform_data gta02_pcf_pdata = {
84                         },
85                 },
86                 [PCF50633_REGULATOR_LDO3] = {
87 -                       .name           = "lcm_3v",
88 +                       .name           = "unused3",
89                         .voltage        = {
90                                 .init   = 3000,
91                                 .max    = 3000,
92 @@ -545,20 +554,28 @@ static struct pcf50633_platform_data gta02_pcf_pdata = {
93                         },
94                 },
95                 [PCF50633_REGULATOR_LDO5] = {
96 -                       .name           = "gl_1v5",
97 +                       .name           = "rf3v",
98                         .voltage        = {
99                                 .init   = 1500,
100                                 .max    = 1500,
101                         },
102                 },
103                 [PCF50633_REGULATOR_LDO6] = {
104 -                       .name           = "user1",
105 +                       .name           = "lcm_3v",
106                         .flags = PMU_VRAIL_F_SUSPEND_ON,
107                         .voltage        = {
108                                 .init   = 0,
109                                 .max    = 3300,
110                         },
111                 },
112 +               [PCF50633_REGULATOR_MEMLDO] = {
113 +                       .name           = "memldo",
114 +                       .flags = PMU_VRAIL_F_SUSPEND_ON,
115 +                       .voltage        = {
116 +                               .init   = 1800,
117 +                               .max    = 1800,
118 +                       },
119 +               },
120         },
121         .defer_resume_backlight = 1,
122  };
123 @@ -611,13 +628,15 @@ static void mangle_pmu_pdata_by_system_rev(void)
124                                                                 .max = 3000,
125                                                         }
126                                                 });
127 -               gta02_pcf_pdata.rails[PCF50633_REGULATOR_LDO6] = ((struct pmu_voltage_rail) {
128 -                                                       .name = "lcm_3v",
129 -                                                       .voltage = {
130 -                                                               .init = 3000,
131 -                                                               .max = 3000,
132 -                                                       }
133 -                                               });
134 +               gta02_pcf_pdata.rails[PCF50633_REGULATOR_LDO6] =
135 +                                       ((struct pmu_voltage_rail) {
136 +                                               .name = "lcm_3v",
137 +                                               .flags = PMU_VRAIL_F_SUSPEND_ON,
138 +                                               .voltage = {
139 +                                                       .init = 3000,
140 +                                                       .max = 3000,
141 +                                               }
142 +                                       });
143                 break;
144         default:
145                 break;
146 diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
147 index 4002c03..37dfca6 100644
148 --- a/drivers/i2c/chips/pcf50633.c
149 +++ b/drivers/i2c/chips/pcf50633.c
150 @@ -750,9 +750,6 @@ static void pcf50633_work(struct work_struct *work)
151         mutex_lock(&pcf->working_lock);
152         pcf->working = 1;
153  
154 -       dev_info(&pcf->client.dev, "pcf50633_work called with suspended = %d\n",
155 -                                  pcf->have_been_suspended);
156 -
157         /*
158          * If we are inside suspend -> resume completion time we don't attempt
159          * service until we have fully resumed.  Although we could talk to the
160 @@ -763,11 +760,8 @@ static void pcf50633_work(struct work_struct *work)
161          * completed.
162          */
163  
164 -       if (pcf->have_been_suspended && (pcf->have_been_suspended < 3)) {
165 -               dev_info(&pcf->client.dev, "rescheduling,  suspended = %d\n",
166 -                                          pcf->have_been_suspended);
167 +       if (pcf->have_been_suspended && (pcf->have_been_suspended < 3))
168                 goto reschedule;
169 -       }
170  
171         /*
172          * datasheet says we have to read the five IRQ
173 @@ -1157,9 +1151,13 @@ static void pcf50633_work(struct work_struct *work)
174  
175  reschedule:
176         /* don't spew, delaying whatever else is happening */
177 -       msleep(100);
178 -
179 -       dev_info(&pcf->client.dev, "rescheduling interrupt service\n");
180 +       /* EXCEPTION: if we are in the middle of suspending, we don't have
181 +        * time to hang around since we may be turned off core 1V3 already
182 +        */
183 +       if (pcf->have_been_suspended != 1) {
184 +               msleep(50);
185 +               dev_info(&pcf->client.dev, "rescheduling interrupt service\n");
186 +       }
187         if (!schedule_work(&pcf->work))
188                 dev_err(&pcf->client.dev, "int service reschedule failed\n");
189  
190 @@ -2333,7 +2331,7 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state)
191                                             PCF50633_REG_AUTOOUT,
192                                             sizeof(pcf->standby_regs.misc),
193                                             &pcf->standby_regs.misc[0]);
194 -       if (ret != 18)
195 +       if (ret != sizeof(pcf->standby_regs.misc))
196                 dev_err(dev, "Failed to save misc levels and enables :-(\n");
197  
198         /* regulator voltages and enable states */
199 @@ -2341,7 +2339,7 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state)
200                                             PCF50633_REG_LDO1OUT,
201                                             sizeof(pcf->standby_regs.ldo),
202                                             &pcf->standby_regs.ldo[0]);
203 -       if (ret != 14)
204 +       if (ret != sizeof(pcf->standby_regs.ldo))
205                 dev_err(dev, "Failed to save LDO levels and enables :-(\n");
206  
207         /* switch off power supplies that are not needed during suspend */
208 @@ -2349,8 +2347,6 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state)
209                 if ((pcf->pdata->rails[i].flags & PMU_VRAIL_F_SUSPEND_ON))
210                         continue;
211  
212 -               dev_dbg(dev, "disabling regulator %u\n", i);
213 -
214                 /* we can save ourselves the read part of a read-modify-write
215                  * here because we captured all these already
216                  */
217 @@ -2359,6 +2355,11 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state)
218                 else
219                         tmp = pcf->standby_regs.ldo[(i - 4) * 2 + 1];
220  
221 +               dev_info(dev, "disabling reg %s by setting ENA %d to 0x%02X\n",
222 +                             pcf->pdata->rails[i].name,
223 +                             regulator_registers[i] + 1, tmp & 0xfe);
224 +
225 +               /* associated enable is always +1 from OUT reg */
226                 __reg_write(pcf, regulator_registers[i] + 1, tmp & 0xfe);
227         }
228  
229 diff --git a/drivers/mfd/glamo/glamo-core.c b/drivers/mfd/glamo/glamo-core.c
230 index 3edbfa8..d4b526d 100644
231 --- a/drivers/mfd/glamo/glamo-core.c
232 +++ b/drivers/mfd/glamo/glamo-core.c
233 @@ -848,6 +848,7 @@ static void glamo_power(struct glamo_core *glamo,
234                                  ARRAY_SIZE(glamo_resume_script), 0);
235  
236                 break;
237 +
238         case GLAMO_POWER_STANDBY:
239                 /* enable memory self-refresh */
240                 __reg_set_bit_mask(glamo, GLAMO_REG_MEM_DRAM1,
241 @@ -859,6 +860,7 @@ static void glamo_power(struct glamo_core *glamo,
242                 __reg_set_bit_mask(glamo, GLAMO_REG_PLL_GEN3, 0x2000, 0xffff);
243                 __reg_set_bit_mask(glamo, GLAMO_REG_DFT_GEN5, 0x0001, 0xffff);
244                 break;
245 +
246         case GLAMO_POWER_SUSPEND:
247                 __reg_set_bit_mask(glamo, GLAMO_REG_MEM_DRAM2,
248                                    GLAMO_MEM_DRAM2_DEEP_PWRDOWN, 0xffff);
249 diff --git a/drivers/video/display/jbt6k74.c b/drivers/video/display/jbt6k74.c
250 index 6fa1fe7..b406298 100644
251 --- a/drivers/video/display/jbt6k74.c
252 +++ b/drivers/video/display/jbt6k74.c
253 @@ -634,6 +634,7 @@ static int jbt_suspend(struct spi_device *spi, pm_message_t state)
254  
255         /* Save mode for resume */
256         jbt->last_state = jbt->state;
257 +
258         jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY);
259  
260         jbt->have_resumed = 0;
261 -- 
262 1.5.6.3
263