changed Makefile and profiles, added patches for kernel 2.6.24
[openwrt.git] / target / linux / s3c24xx / patches-2.6.24 / 1187-fix-pcf50633-use-i2c-bulk-autoincrement.patch.patch
1 From 8a2d04c222684e3278dd28d11f57a05fe0865183 Mon Sep 17 00:00:00 2001
2 From: Andy Green <andy@openmoko.com>
3 Date: Wed, 2 Jul 2008 22:40:12 +0100
4 Subject: [PATCH] fix-pcf50633-use-i2c-bulk-autoincrement.patch
5
6 Simplify and speed up bulk sequential I2C actions in pcf50633
7 the time savings are pretty considerable and so is the simplification
8
9 Signed-off-by: Andy Green <andy@openmoko.com>
10 ---
11  drivers/i2c/chips/pcf50633.c |  117 +++++++++++++++++++++++++-----------------
12  1 files changed, 70 insertions(+), 47 deletions(-)
13
14 diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
15 index 1f88c32..96857a3 100644
16 --- a/drivers/i2c/chips/pcf50633.c
17 +++ b/drivers/i2c/chips/pcf50633.c
18 @@ -156,14 +156,14 @@ struct pcf50633_data {
19  
20  #ifdef CONFIG_PM
21         struct {
22 -               u_int8_t int1m, int2m, int3m, int4m, int5m;
23                 u_int8_t ooctim2;
24 -               u_int8_t autoout, autoena, automxc;
25 -               u_int8_t down1out, down1mxc;
26 -               u_int8_t down2out, down2ena;
27 -               u_int8_t memldoout, memldoena;
28 -               u_int8_t ledout, ledena, leddim;
29 -               u_int8_t ldo[__NUM_PCF50633_REGS][2];
30 +               /* enables are always [1] below
31 +                * I2C has limit of 32 sequential regs, so done in two lumps
32 +                * because it covers 33 register extent otherwise
33 +                */
34 +               u_int8_t misc[PCF50633_REG_LEDDIM - PCF50633_REG_AUTOOUT + 1];
35 +               /*  skip 1 reserved reg here */
36 +               u_int8_t ldo[PCF50633_REG_HCLDOENA - PCF50633_REG_LDO1OUT + 1];
37         } standby_regs;
38  
39         struct resume_dependency resume_dependency;
40 @@ -1737,6 +1737,8 @@ static int pcf50633bl_set_intensity(struct backlight_device *bd)
41         int old_intensity = reg_read(pcf, PCF50633_REG_LEDOUT);
42         int ret;
43  
44 +       dev_info(&pcf->client.dev, "pcf50633bl_set_intensity\n");
45 +
46         if (!(reg_read(pcf, PCF50633_REG_LEDENA) & 1))
47                 old_intensity = 0;
48  
49 @@ -2221,6 +2223,9 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state)
50         int i;
51         int ret;
52         u_int8_t tmp;
53 +       u_int8_t res[5];
54 +
55 +       dev_err(dev, "pcf50633_suspend\n");
56  
57         /* we suspend once (!) as late as possible in the suspend sequencing */
58  
59 @@ -2228,30 +2233,26 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state)
60                 return 0;
61  
62         /* The general idea is to power down all unused power supplies,
63 -        * and then mask all PCF50606 interrup sources but EXTONR, ONKEYF
64 +        * and then mask all PCF50633 interrupt sources but EXTONR, ONKEYF
65          * and ALARM */
66  
67         mutex_lock(&pcf->lock);
68  
69         /* Save all registers that don't "survive" standby state */
70         pcf->standby_regs.ooctim2 = __reg_read(pcf, PCF50633_REG_OOCTIM2);
71 -       pcf->standby_regs.autoout = __reg_read(pcf, PCF50633_REG_AUTOOUT);
72 -       pcf->standby_regs.autoena = __reg_read(pcf, PCF50633_REG_AUTOENA);
73 -       pcf->standby_regs.automxc = __reg_read(pcf, PCF50633_REG_AUTOMXC);
74 -       pcf->standby_regs.down1out = __reg_read(pcf, PCF50633_REG_DOWN1OUT);
75 -       pcf->standby_regs.down1mxc = __reg_read(pcf, PCF50633_REG_DOWN1MXC);
76 -       pcf->standby_regs.down2out = __reg_read(pcf, PCF50633_REG_DOWN2OUT);
77 -       pcf->standby_regs.down2ena = __reg_read(pcf, PCF50633_REG_DOWN2ENA);
78 -       pcf->standby_regs.memldoout = __reg_read(pcf, PCF50633_REG_MEMLDOOUT);
79 -       pcf->standby_regs.memldoena = __reg_read(pcf, PCF50633_REG_MEMLDOENA);
80 -       pcf->standby_regs.ledout = __reg_read(pcf, PCF50633_REG_LEDOUT);
81 -       pcf->standby_regs.ledena = __reg_read(pcf, PCF50633_REG_LEDENA);
82 -       pcf->standby_regs.leddim = __reg_read(pcf, PCF50633_REG_LEDDIM);
83 +
84 +       ret = i2c_smbus_read_i2c_block_data(&pcf->client,
85 +                                           PCF50633_REG_AUTOOUT,
86 +                                           sizeof(pcf->standby_regs.misc),
87 +                                           &pcf->standby_regs.misc[0]);
88 +       if (ret != 18)
89 +               dev_err(dev, "Failed to save misc levels and enables :-(\n");
90  
91         /* regulator voltages and enable states */
92         ret = i2c_smbus_read_i2c_block_data(&pcf->client,
93 -                                           PCF50633_REG_LDO1OUT, 14,
94 -                                           &pcf->standby_regs.ldo[0][0]);
95 +                                           PCF50633_REG_LDO1OUT,
96 +                                           sizeof(pcf->standby_regs.ldo),
97 +                                           &pcf->standby_regs.ldo[0]);
98         if (ret != 14)
99                 dev_err(dev, "Failed to save LDO levels and enables :-(\n");
100  
101 @@ -2261,11 +2262,16 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state)
102                         continue;
103  
104                 dev_dbg(dev, "disabling regulator %u\n", i);
105 -               /* we cannot use pcf50633_onoff_set() because we're
106 -                * already under the mutex */
107 -               tmp = __reg_read(pcf, regulator_registers[i]+1);
108 -               tmp &= 0xfe;
109 -               __reg_write(pcf, regulator_registers[i]+1, tmp);
110 +
111 +               /* we can save ourselves the read part of a read-modify-write
112 +                * here because we captured all these already
113 +                */
114 +               if (i < 4)
115 +                       tmp = pcf->standby_regs.misc[i * 4 + 1];
116 +               else
117 +                       tmp = pcf->standby_regs.ldo[(i - 4) * 2 + 1];
118 +
119 +               __reg_write(pcf, regulator_registers[i] + 1, tmp & 0xfe);
120         }
121  
122         /* turn off the backlight */
123 @@ -2276,11 +2282,14 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state)
124         /* set interrupt masks so only those sources we want to wake
125          * us are able to
126          */
127 -       __reg_write(pcf, PCF50633_REG_INT1M, ~pcf->pdata->resumers[0]);
128 -       __reg_write(pcf, PCF50633_REG_INT2M, ~pcf->pdata->resumers[1]);
129 -       __reg_write(pcf, PCF50633_REG_INT3M, ~pcf->pdata->resumers[2]);
130 -       __reg_write(pcf, PCF50633_REG_INT4M, ~pcf->pdata->resumers[3]);
131 -       __reg_write(pcf, PCF50633_REG_INT5M, ~pcf->pdata->resumers[4]);
132 +       for (i = 0; i < 5; i++)
133 +               res[i] = ~pcf->pdata->resumers[i];
134 +
135 +       ret = i2c_smbus_write_i2c_block_data(&pcf->client,
136 +                                            PCF50633_REG_INT1M,
137 +                                            5, &res[0]);
138 +       if (ret)
139 +               dev_err(dev, "Failed to set wake masks :-( %d\n", ret);
140  
141         pcf->have_been_suspended = 1;
142  
143 @@ -2312,9 +2321,12 @@ EXPORT_SYMBOL_GPL(pcf50633_ready);
144  void pcf50633_backlight_resume(struct pcf50633_data *pcf)
145  {
146         /* we force the backlight on in fact */
147 -       __reg_write(pcf, PCF50633_REG_LEDOUT, pcf->standby_regs.ledout);
148 -       __reg_write(pcf, PCF50633_REG_LEDENA, pcf->standby_regs.ledena | 0x01);
149 -       __reg_write(pcf, PCF50633_REG_LEDDIM, pcf->standby_regs.leddim);
150 +       __reg_write(pcf, PCF50633_REG_LEDOUT, pcf->standby_regs.misc[
151 +                                  PCF50633_REG_LEDOUT - PCF50633_REG_AUTOOUT]);
152 +       __reg_write(pcf, PCF50633_REG_LEDENA, pcf->standby_regs.misc[
153 +                              PCF50633_REG_LEDENA - PCF50633_REG_AUTOOUT] | 1);
154 +       __reg_write(pcf, PCF50633_REG_LEDDIM, pcf->standby_regs.misc[
155 +                                  PCF50633_REG_LEDDIM - PCF50633_REG_AUTOOUT]);
156  }
157  EXPORT_SYMBOL_GPL(pcf50633_backlight_resume);
158  
159 @@ -2324,7 +2336,10 @@ static int pcf50633_resume(struct device *dev)
160         struct i2c_client *client = to_i2c_client(dev);
161         struct pcf50633_data *pcf = i2c_get_clientdata(client);
162         int ret;
163 +       u8 res[5];
164  
165 +       dev_info(dev, "pcf50633_resume suspended on entry = %d\n",
166 +                                                     pcf->have_been_suspended);
167         mutex_lock(&pcf->lock);
168  
169         pcf->have_been_suspended = 2; /* resuming */
170 @@ -2332,14 +2347,14 @@ static int pcf50633_resume(struct device *dev)
171         /* these guys get reset while pcf50633 is suspend state, refresh */
172  
173         __reg_write(pcf, PCF50633_REG_OOCTIM2, pcf->standby_regs.ooctim2);
174 -       __reg_write(pcf, PCF50633_REG_AUTOOUT, pcf->standby_regs.autoout);
175 -       __reg_write(pcf, PCF50633_REG_AUTOMXC, pcf->standby_regs.automxc);
176 -       __reg_write(pcf, PCF50633_REG_DOWN1OUT, pcf->standby_regs.down1out);
177 -       __reg_write(pcf, PCF50633_REG_DOWN1MXC, pcf->standby_regs.down1mxc);
178 -       __reg_write(pcf, PCF50633_REG_DOWN2OUT, pcf->standby_regs.down2out);
179 -       __reg_write(pcf, PCF50633_REG_DOWN2ENA, pcf->standby_regs.down2ena);
180 -       __reg_write(pcf, PCF50633_REG_MEMLDOOUT, pcf->standby_regs.memldoout);
181 -       __reg_write(pcf, PCF50633_REG_MEMLDOENA, pcf->standby_regs.memldoena);
182 +
183 +       /* regulator voltages and enable states */
184 +       ret = i2c_smbus_write_i2c_block_data(&pcf->client,
185 +                                            PCF50633_REG_AUTOOUT,
186 +                                            sizeof(pcf->standby_regs.misc) - 4,
187 +                                            &pcf->standby_regs.misc[0]);
188 +       if (ret)
189 +               dev_err(dev, "Failed to restore misc :-( %d\n", ret);
190  
191         /* platform can choose to defer backlight bringup */
192         if (!pcf->pdata->defer_resume_backlight)
193 @@ -2347,14 +2362,22 @@ static int pcf50633_resume(struct device *dev)
194  
195         /* regulator voltages and enable states */
196         ret = i2c_smbus_write_i2c_block_data(&pcf->client,
197 -                                           PCF50633_REG_LDO1OUT, 14,
198 -                                           &pcf->standby_regs.ldo[0][0]);
199 +                                            PCF50633_REG_LDO1OUT,
200 +                                            sizeof(pcf->standby_regs.ldo),
201 +                                            &pcf->standby_regs.ldo[0]);
202         if (ret)
203                 dev_err(dev, "Failed to restore LDOs :-( %d\n", ret);
204  
205 -       mutex_unlock(&pcf->lock);
206 +       memset(res, 0, sizeof(res));
207 +       ret = i2c_smbus_write_i2c_block_data(&pcf->client,
208 +                                            PCF50633_REG_INT1M,
209 +                                            5, &res[0]);
210 +       if (ret)
211 +               dev_err(dev, "Failed to set int masks :-( %d\n", ret);
212  
213 -       pcf50633_irq(pcf->irq, pcf);
214 +       pcf->have_been_suspended = 3; /* resume completed */
215 +
216 +       mutex_unlock(&pcf->lock);
217  
218         callback_all_resume_dependencies(&pcf->resume_dependency);
219  
220 -- 
221 1.5.6.5
222