1 From 530be0418a0d05cad538ff62ae16b43d2d4462e3 Mon Sep 17 00:00:00 2001
2 From: mokopatches <mokopatches@openmoko.org>
3 Date: Sun, 13 Apr 2008 07:23:57 +0100
4 Subject: [PATCH] fix-pcf50606-LOWBAT-kill-init.patch
7 drivers/i2c/chips/pcf50606.c | 53 ++++++++++++++++++++++++++++++++++++-----
8 1 files changed, 46 insertions(+), 7 deletions(-)
10 diff --git a/drivers/i2c/chips/pcf50606.c b/drivers/i2c/chips/pcf50606.c
11 index b530583..a1c92d3 100644
12 --- a/drivers/i2c/chips/pcf50606.c
13 +++ b/drivers/i2c/chips/pcf50606.c
14 @@ -654,8 +654,20 @@ static void pcf50606_work(struct work_struct *work)
15 if (pcf->onkey_seconds >=
16 pcf->pdata->onkey_seconds_required) {
17 /* Ask init to do 'ctrlaltdel' */
18 - DEBUGPC("SIGINT(init) ");
19 - kill_proc(1, SIGINT, 1);
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
30 + if (find_task_by_pid(1)) {
31 + kill_proc(1, SIGINT, 1);
32 + DEBUGPC("SIGINT(init) ");
34 /* FIXME: what to do if userspace doesn't
35 * shut down? Do we want to force it? */
37 @@ -749,11 +761,38 @@ static void pcf50606_work(struct work_struct *work)
40 if (pcfirq[2] & PCF50606_INT3_LOWBAT) {
41 - /* Really low battery voltage, we have 8 seconds left */
43 - apm_queue_event(APM_LOW_BATTERY);
44 - DEBUGPC("SIGPWR(init) ");
45 - kill_proc(1, SIGPWR, 1);
46 + if (__reg_read(pcf, PCF50606_REG_OOCS) & PCF50606_OOCS_EXTON) {
48 + * hey no need to freak out, we have some kind of
49 + * valid charger power
51 + DEBUGPC("(NO)BAT ");
53 + /* Really low battery voltage, we have 8 seconds left */
56 + * currently Linux reacts badly to issuing a signal to
57 + * PID #1 before init is started. What happens is that
58 + * the next kernel thread to start, which is the JFFS2
59 + * Garbage collector in our case, gets the signal
60 + * instead and proceeds to fail to fork -- which is
61 + * very bad. Therefore we confirm PID #1 exists
62 + * before issuing SPIGPWR
64 + if (find_task_by_pid(1)) {
65 + apm_queue_event(APM_LOW_BATTERY);
66 + DEBUGPC("SIGPWR(init) ");
67 + kill_proc(1, SIGPWR, 1);
70 + * well, our situation is like this: we do not
71 + * have any external power, we have a low
72 + * battery and since PID #1 doesn't exist yet,
73 + * we are early in the boot, likely before
74 + * rootfs mount. We should just call it a day
76 + apm_queue_event(APM_CRITICAL_SUSPEND);
78 /* Tell PMU we are taking care of this */
79 reg_set_bit_mask(pcf, PCF50606_REG_OOCC1,
80 PCF50606_OOCC1_TOTRST,