add support for target 3c24xx (more known as Openmoko GTA02 "Freerunner") and merge...
[openwrt.git] / target / linux / s3c24xx / patches / 0058-fix-pcf50633-LOWBAT-kill-init.patch.patch
1 From 6d3172ba9f1b4a650c8fdb3b6e11dc71852fe6d1 Mon Sep 17 00:00:00 2001
2 From: mokopatches <mokopatches@openmoko.org>
3 Date: Fri, 25 Jul 2008 22:21:25 +0100
4 Subject: [PATCH] fix-pcf50633-LOWBAT-kill-init.patch
5
6 ---
7  drivers/i2c/chips/pcf50633.c |   56 ++++++++++++++++++++++++++++++++++++-----
8  1 files changed, 49 insertions(+), 7 deletions(-)
9
10 diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
11 index 0cf5e53..fc1262e 100644
12 --- a/drivers/i2c/chips/pcf50633.c
13 +++ b/drivers/i2c/chips/pcf50633.c
14 @@ -690,8 +690,20 @@ static void pcf50633_work(struct work_struct *work)
15                         if (pcf->onkey_seconds >=
16                             pcf->pdata->onkey_seconds_sig_init) {
17                                 /* Ask init to do 'ctrlaltdel' */
18 -                               DEBUGPC("SIGINT(init) ");
19 -                               kill_proc(1, SIGINT, 1);
20 +                               /*
21 +                                * currently Linux reacts badly to issuing a
22 +                                * signal to PID #1 before init is started.
23 +                                * What happens is that the next kernel thread
24 +                                * to start, which is the JFFS2 Garbage
25 +                                * collector in our case, gets the signal
26 +                                * instead and proceeds to fail to fork --
27 +                                * which is very bad.  Therefore we confirm
28 +                                * PID #1 exists before issuing the signal
29 +                                */
30 +                               if (find_task_by_pid(1)) {
31 +                                       DEBUGPC("SIGINT(init) ");
32 +                                       kill_proc(1, SIGINT, 1);
33 +                               }
34                                 /* FIXME: what if userspace doesn't shut down? */
35                         }
36                         if (pcf->onkey_seconds >=
37 @@ -790,11 +802,41 @@ static void pcf50633_work(struct work_struct *work)
38         }
39  
40         if (pcfirq[3] & (PCF50633_INT4_LOWBAT|PCF50633_INT4_LOWSYS)) {
41 -               /* Really low battery voltage, we have 8 seconds left */
42 -               DEBUGPC("LOWBAT ");
43 -               apm_queue_event(APM_LOW_BATTERY);
44 -               DEBUGPC("SIGPWR(init) ");
45 -               kill_proc(1, SIGPWR, 1);
46 +               if ((__reg_read(pcf, PCF50633_REG_MBCS1) &
47 +                   (PCF50633_MBCS1_USBPRES | PCF50633_MBCS1_USBOK)) ==
48 +                   (PCF50633_MBCS1_USBPRES | PCF50633_MBCS1_USBOK)) {
49 +                       /*
50 +                        * hey no need to freak out, we have some kind of
51 +                        * valid charger power
52 +                        */
53 +                       DEBUGPC("(NO)BAT ");
54 +               } else {
55 +                       /* Really low battery voltage, we have 8 seconds left */
56 +                       DEBUGPC("LOWBAT ");
57 +                       /*
58 +                        * currently Linux reacts badly to issuing a signal to
59 +                        * PID #1 before init is started.  What happens is that
60 +                        * the next kernel thread to start, which is the JFFS2
61 +                        * Garbage collector in our case, gets the signal
62 +                        * instead and proceeds to fail to fork -- which is
63 +                        * very bad.  Therefore we confirm PID #1 exists
64 +                        * before issuing SPIGPWR
65 +                        */
66 +                       if (find_task_by_pid(1)) {
67 +                               apm_queue_event(APM_LOW_BATTERY);
68 +                               DEBUGPC("SIGPWR(init) ");
69 +                               kill_proc(1, SIGPWR, 1);
70 +                       } else
71 +                               /*
72 +                                * well, our situation is like this:  we do not
73 +                                * have any external power, we have a low
74 +                                * battery and since PID #1 doesn't exist yet,
75 +                                * we are early in the boot, likely before
76 +                                * rootfs mount.  We should just call it a day
77 +                                */
78 +                               apm_queue_event(APM_CRITICAL_SUSPEND);
79 +               }
80 +
81                 /* Tell PMU we are taking care of this */
82                 reg_set_bit_mask(pcf, PCF50633_REG_OOCSHDWN,
83                                  PCF50633_OOCSHDWN_TOTRST,
84 -- 
85 1.5.6.3
86