add support for target 3c24xx (more known as Openmoko GTA02 "Freerunner") and merge...
[openwrt.git] / target / linux / s3c24xx / patches / 0142-add-resume-reason-sysfs.patch.patch
1 From 95b8e195427ce0c6b495925813d7e10949af8ce3 Mon Sep 17 00:00:00 2001
2 From: Andy Green <andy@openmoko.com>
3 Date: Fri, 25 Jul 2008 23:06:10 +0100
4 Subject: [PATCH] add-resume-reason-sysfs.patch
5
6 If you have U-Boot with uboot-add-find-wake-reason.patch, this
7 patch will get you a wake reason report from
8
9 cat /sys/devices/platform/neo1973-resume.0/resume_reason
10
11 it looks like this:
12
13   EINT00_ACCEL1
14   EINT01_GSM
15   EINT02_BLUETOOTH
16   EINT03_DEBUGBRD
17   EINT04_JACK
18   EINT05_WLAN
19   EINT06_AUXKEY
20   EINT07_HOLDKEY
21   EINT08_ACCEL2
22 * EINT09_PMU
23     adpins
24     adprem
25     usbins
26     usbrem
27     rtcalarm
28     second
29     onkeyr
30     onkeyf
31     exton1r
32     exton1f
33     exton2r
34     exton2f
35     exton3r
36     exton3f
37   * batfull
38     chghalt
39     thlimon
40     thlimoff
41     usblimon
42     usblimoff
43     adcrdy
44     onkey1s
45     lowsys
46     lowbat
47     hightmp
48     autopwrfail
49     dwn1pwrfail
50     dwn2pwrfail
51     ledpwrfail
52     ledovp
53     ldo1pwrfail
54     ldo2pwrfail
55     ldo3pwrfail
56     ldo4pwrfail
57     ldo5pwrfail
58     ldo6pwrfail
59     hcidopwrfail
60     hcidoovl
61   EINT10_NULL
62   EINT11_NULL
63   EINT12_GLAMO
64   EINT13_NULL
65   EINT14_NULL
66   EINT15_NULL
67
68 This shows a problem, false wake from suspend due to battery full
69
70 Signed-off-by: Andy Green <andy@openmoko.com>
71 ---
72  arch/arm/mach-s3c2440/mach-gta02.c               |    5 +
73  arch/arm/plat-s3c24xx/Makefile                   |    4 +-
74  arch/arm/plat-s3c24xx/neo1973_pm_resume_reason.c |  134 ++++++++++++++++++++++
75  drivers/i2c/chips/pcf50633.c                     |   80 +++++++++++++
76  include/linux/pcf50633.h                         |    6 +
77  5 files changed, 227 insertions(+), 2 deletions(-)
78  create mode 100644 arch/arm/plat-s3c24xx/neo1973_pm_resume_reason.c
79
80 diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
81 index 9e8fae7..90b62c1 100644
82 --- a/arch/arm/mach-s3c2440/mach-gta02.c
83 +++ b/arch/arm/mach-s3c2440/mach-gta02.c
84 @@ -378,6 +378,10 @@ struct platform_device gta02_version_device = {
85         .num_resources  = 0,
86  };
87  
88 +struct platform_device gta02_resume_reason_device = {
89 +       .name           = "neo1973-resume",
90 +       .num_resources  = 0,
91 +};
92  
93  static struct map_desc gta02_iodesc[] __initdata = {
94         {
95 @@ -737,6 +741,7 @@ static struct platform_device *gta02_devices[] __initdata = {
96         &gta02_nor_flash,
97         &sc32440_fiq_device,
98         &gta02_version_device,
99 +       &gta02_resume_reason_device,
100         &s3c24xx_pwm_device,
101  };
102  
103 diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
104 index c173f7b..f60dc5f 100644
105 --- a/arch/arm/plat-s3c24xx/Makefile
106 +++ b/arch/arm/plat-s3c24xx/Makefile
107 @@ -34,5 +34,5 @@ obj-$(CONFIG_MACH_NEO1973)    += neo1973_version.o \
108                                    neo1973_pm_gsm.o \
109                                    neo1973_pm_gps.o \
110                                    neo1973_pm_bt.o  \
111 -                                  neo1973_shadow.o
112 -
113 +                                  neo1973_shadow.o \
114 +                                  neo1973_pm_resume_reason.o
115 diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_resume_reason.c b/arch/arm/plat-s3c24xx/neo1973_pm_resume_reason.c
116 new file mode 100644
117 index 0000000..cca42dc
118 --- /dev/null
119 +++ b/arch/arm/plat-s3c24xx/neo1973_pm_resume_reason.c
120 @@ -0,0 +1,134 @@
121 +/*
122 + * Resume reason sysfs for the FIC Neo1973 GSM Phone
123 + *
124 + * (C) 2008 by Openmoko Inc.
125 + * Author: Andy Green <andy@openmoko.com>
126 + * All rights reserved.
127 + *
128 + * This program is free software; you can redistribute it and/or modify
129 + * it under the terms of the GNU General Public License resume_reason 2 as
130 + * published by the Free Software Foundation
131 + *
132 + */
133 +
134 +#include <linux/module.h>
135 +#include <linux/init.h>
136 +#include <linux/kernel.h>
137 +#include <linux/platform_device.h>
138 +#include <linux/io.h>
139 +
140 +#include <asm/hardware.h>
141 +#include <asm/mach-types.h>
142 +
143 +#ifdef CONFIG_MACH_NEO1973_GTA02
144 +#include <asm/arch/gta02.h>
145 +#include <linux/pcf50633.h>
146 +
147 +
148 +static unsigned int *gstatus4_mapped;
149 +static char *resume_reasons[] = {
150 +       "EINT00_ACCEL1",
151 +       "EINT01_GSM",
152 +       "EINT02_BLUETOOTH",
153 +       "EINT03_DEBUGBRD",
154 +       "EINT04_JACK",
155 +       "EINT05_WLAN",
156 +       "EINT06_AUXKEY",
157 +       "EINT07_HOLDKEY",
158 +       "EINT08_ACCEL2",
159 +       "EINT09_PMU",
160 +       "EINT10_NULL",
161 +       "EINT11_NULL",
162 +       "EINT12_GLAMO",
163 +       "EINT13_NULL",
164 +       "EINT14_NULL",
165 +       "EINT15_NULL",
166 +       NULL
167 +};
168 +
169 +static ssize_t resume_reason_read(struct device *dev,
170 +                                 struct device_attribute *attr,
171 +                                 char *buf)
172 +{
173 +       int bit = 0;
174 +       char *end = buf;
175 +
176 +       for (bit = 0; resume_reasons[bit]; bit++) {
177 +               if ((*gstatus4_mapped) & (1 << bit))
178 +                       end += sprintf(end, "* %s\n", resume_reasons[bit]);
179 +               else
180 +                       end += sprintf(end, "  %s\n", resume_reasons[bit]);
181 +
182 +               if (bit == 9) /* PMU */
183 +                       end += pcf50633_report_resumers(pcf50633_global, end);
184 +       }
185 +
186 +       return end - buf;
187 +}
188 +
189 +
190 +static DEVICE_ATTR(resume_reason, 0644, resume_reason_read, NULL);
191 +
192 +static struct attribute *neo1973_resume_reason_sysfs_entries[] = {
193 +       &dev_attr_resume_reason.attr,
194 +       NULL
195 +};
196 +
197 +static struct attribute_group neo1973_resume_reason_attr_group = {
198 +       .name   = NULL,
199 +       .attrs  = neo1973_resume_reason_sysfs_entries,
200 +};
201 +
202 +static int __init neo1973_resume_reason_probe(struct platform_device *pdev)
203 +{
204 +       dev_info(&pdev->dev, "starting\n");
205 +
206 +       switch (machine_arch_type) {
207 +#ifdef CONFIG_MACH_NEO1973_GTA01
208 +       case MACH_TYPE_NEO1973_GTA01:
209 +               return -EINVAL;
210 +#endif /* CONFIG_MACH_NEO1973_GTA01 */
211 +       default:
212 +               gstatus4_mapped = ioremap(0x560000BC, 0x4);
213 +               if (!gstatus4_mapped) {
214 +                       dev_err(&pdev->dev, "failed to ioremap() memory region\n");
215 +                       return -EINVAL;
216 +               }
217 +               break;
218 +       }
219 +
220 +       return sysfs_create_group(&pdev->dev.kobj, &neo1973_resume_reason_attr_group);
221 +}
222 +
223 +static int neo1973_resume_reason_remove(struct platform_device *pdev)
224 +{
225 +       sysfs_remove_group(&pdev->dev.kobj, &neo1973_resume_reason_attr_group);
226 +       iounmap(gstatus4_mapped);
227 +       return 0;
228 +}
229 +
230 +static struct platform_driver neo1973_resume_reason_driver = {
231 +       .probe          = neo1973_resume_reason_probe,
232 +       .remove         = neo1973_resume_reason_remove,
233 +       .driver         = {
234 +               .name           = "neo1973-resume",
235 +       },
236 +};
237 +
238 +static int __devinit neo1973_resume_reason_init(void)
239 +{
240 +       return platform_driver_register(&neo1973_resume_reason_driver);
241 +}
242 +
243 +static void neo1973_resume_reason_exit(void)
244 +{
245 +       platform_driver_unregister(&neo1973_resume_reason_driver);
246 +}
247 +
248 +module_init(neo1973_resume_reason_init);
249 +module_exit(neo1973_resume_reason_exit);
250 +
251 +MODULE_LICENSE("GPL");
252 +MODULE_AUTHOR("Andy Green <andy@openmoko.com>");
253 +MODULE_DESCRIPTION("Neo1973 resume_reason");
254 +#endif
255 diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
256 index da58aa3..d2ff2c1 100644
257 --- a/drivers/i2c/chips/pcf50633.c
258 +++ b/drivers/i2c/chips/pcf50633.c
259 @@ -120,6 +120,8 @@ struct pcf50633_data {
260         int allow_close;
261         int onkey_seconds;
262         int irq;
263 +       int have_been_suspended;
264 +       unsigned char pcfirq_resume[5];
265  
266         int coldplug_done; /* cleared by probe, set by first work service */
267         int flag_bat_voltage_read; /* ipc to /sys batt voltage read func */
268 @@ -597,6 +599,17 @@ static void pcf50633_work(struct work_struct *work)
269                 return;
270         }
271  
272 +       /* hey did we just resume? */
273 +
274 +       if (pcf->have_been_suspended) {
275 +               pcf->have_been_suspended = 0;
276 +               /*
277 +                * grab a copy of resume interrupt reasons
278 +                * from pcf50633 POV
279 +                */
280 +               memcpy(pcf->pcfirq_resume, pcfirq, sizeof(pcf->pcfirq_resume));
281 +       }
282 +
283         if (!pcf->coldplug_done) {
284                 DEBUGP("PMU Coldplug init\n");
285  
286 @@ -1856,6 +1869,71 @@ static int pcf50633_detach_client(struct i2c_client *client)
287         return 0;
288  }
289  
290 +/* you're going to need >300 bytes in buf */
291 +
292 +int pcf50633_report_resumers(struct pcf50633_data *pcf, char *buf)
293 +{
294 +       static char *int_names[] = {
295 +               "adpins",
296 +               "adprem",
297 +               "usbins",
298 +               "usbrem",
299 +               NULL,
300 +               NULL,
301 +               "rtcalarm",
302 +               "second",
303 +
304 +               "onkeyr",
305 +               "onkeyf",
306 +               "exton1r",
307 +               "exton1f",
308 +               "exton2r",
309 +               "exton2f",
310 +               "exton3r",
311 +               "exton3f",
312 +
313 +               "batfull",
314 +               "chghalt",
315 +               "thlimon",
316 +               "thlimoff",
317 +               "usblimon",
318 +               "usblimoff",
319 +               "adcrdy",
320 +               "onkey1s",
321 +
322 +               "lowsys",
323 +               "lowbat",
324 +               "hightmp",
325 +               "autopwrfail",
326 +               "dwn1pwrfail",
327 +               "dwn2pwrfail",
328 +               "ledpwrfail",
329 +               "ledovp",
330 +
331 +               "ldo1pwrfail",
332 +               "ldo2pwrfail",
333 +               "ldo3pwrfail",
334 +               "ldo4pwrfail",
335 +               "ldo5pwrfail",
336 +               "ldo6pwrfail",
337 +               "hcidopwrfail",
338 +               "hcidoovl"
339 +       };
340 +       char *end = buf;
341 +       int n;
342 +
343 +       for (n = 0; n < 40; n++)
344 +               if (int_names[n]) {
345 +                       if (pcf->pcfirq_resume[n >> 3] & (1 >> (n & 7)))
346 +                               end += sprintf(end, "  * %s\n", int_names[n]);
347 +                       else
348 +                               end += sprintf(end, "    %s\n", int_names[n]);
349 +               }
350 +       
351 +       return end - buf;
352 +}
353 +
354 +
355  #ifdef CONFIG_PM
356  #define INT1M_RESUMERS (PCF50633_INT1_ADPINS           | \
357                          PCF50633_INT1_ADPREM           | \
358 @@ -1938,6 +2016,8 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state)
359         __reg_write(pcf, PCF50633_REG_INT4M, ~INT4M_RESUMERS & 0xff);
360         __reg_write(pcf, PCF50633_REG_INT5M, ~INT5M_RESUMERS & 0xff);
361  
362 +       pcf->have_been_suspended = 1;
363 +
364         mutex_unlock(&pcf->lock);
365  
366         return 0;
367 diff --git a/include/linux/pcf50633.h b/include/linux/pcf50633.h
368 index f427985..39d919d 100644
369 --- a/include/linux/pcf50633.h
370 +++ b/include/linux/pcf50633.h
371 @@ -64,6 +64,12 @@ pcf50633_charge_enable(struct pcf50633_data *pcf, int on);
372  extern void
373  pcf50633_backlight_resume(struct pcf50633_data *pcf);
374  
375 +extern u_int16_t
376 +pcf50633_battvolt(struct pcf50633_data *pcf);
377 +
378 +extern int
379 +pcf50633_report_resumers(struct pcf50633_data *pcf, char *buf);
380 +
381  #define PCF50633_FEAT_EXTON    0x00000001      /* not yet supported */
382  #define PCF50633_FEAT_MBC      0x00000002
383  #define PCF50633_FEAT_BBC      0x00000004      /* not yet supported */
384 -- 
385 1.5.6.3
386