aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/s3c24xx/patches-2.6.24/1068-fix-pcf50633-LOWBAT-kill-init.patch.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/s3c24xx/patches-2.6.24/1068-fix-pcf50633-LOWBAT-kill-init.patch.patch')
-rw-r--r--target/linux/s3c24xx/patches-2.6.24/1068-fix-pcf50633-LOWBAT-kill-init.patch.patch86
1 files changed, 86 insertions, 0 deletions
diff --git a/target/linux/s3c24xx/patches-2.6.24/1068-fix-pcf50633-LOWBAT-kill-init.patch.patch b/target/linux/s3c24xx/patches-2.6.24/1068-fix-pcf50633-LOWBAT-kill-init.patch.patch
new file mode 100644
index 0000000000..2bbc782900
--- /dev/null
+++ b/target/linux/s3c24xx/patches-2.6.24/1068-fix-pcf50633-LOWBAT-kill-init.patch.patch
@@ -0,0 +1,86 @@
+From 5a95dab616822e33d6526965b46eae98717537ea Mon Sep 17 00:00:00 2001
+From: mokopatches <mokopatches@openmoko.org>
+Date: Sun, 13 Apr 2008 07:23:58 +0100
+Subject: [PATCH] fix-pcf50633-LOWBAT-kill-init.patch
+
+---
+ drivers/i2c/chips/pcf50633.c | 56 ++++++++++++++++++++++++++++++++++++-----
+ 1 files changed, 49 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
+index 0cf5e53..fc1262e 100644
+--- a/drivers/i2c/chips/pcf50633.c
++++ b/drivers/i2c/chips/pcf50633.c
+@@ -690,8 +690,20 @@ static void pcf50633_work(struct work_struct *work)
+ if (pcf->onkey_seconds >=
+ pcf->pdata->onkey_seconds_sig_init) {
+ /* Ask init to do 'ctrlaltdel' */
+- DEBUGPC("SIGINT(init) ");
+- kill_proc(1, SIGINT, 1);
++ /*
++ * currently Linux reacts badly to issuing a
++ * signal to PID #1 before init is started.
++ * What happens is that the next kernel thread
++ * to start, which is the JFFS2 Garbage
++ * collector in our case, gets the signal
++ * instead and proceeds to fail to fork --
++ * which is very bad. Therefore we confirm
++ * PID #1 exists before issuing the signal
++ */
++ if (find_task_by_pid(1)) {
++ DEBUGPC("SIGINT(init) ");
++ kill_proc(1, SIGINT, 1);
++ }
+ /* FIXME: what if userspace doesn't shut down? */
+ }
+ if (pcf->onkey_seconds >=
+@@ -790,11 +802,41 @@ static void pcf50633_work(struct work_struct *work)
+ }
+
+ if (pcfirq[3] & (PCF50633_INT4_LOWBAT|PCF50633_INT4_LOWSYS)) {
+- /* Really low battery voltage, we have 8 seconds left */
+- DEBUGPC("LOWBAT ");
+- apm_queue_event(APM_LOW_BATTERY);
+- DEBUGPC("SIGPWR(init) ");
+- kill_proc(1, SIGPWR, 1);
++ if ((__reg_read(pcf, PCF50633_REG_MBCS1) &
++ (PCF50633_MBCS1_USBPRES | PCF50633_MBCS1_USBOK)) ==
++ (PCF50633_MBCS1_USBPRES | PCF50633_MBCS1_USBOK)) {
++ /*
++ * hey no need to freak out, we have some kind of
++ * valid charger power
++ */
++ DEBUGPC("(NO)BAT ");
++ } else {
++ /* Really low battery voltage, we have 8 seconds left */
++ DEBUGPC("LOWBAT ");
++ /*
++ * currently Linux reacts badly to issuing a signal to
++ * PID #1 before init is started. What happens is that
++ * the next kernel thread to start, which is the JFFS2
++ * Garbage collector in our case, gets the signal
++ * instead and proceeds to fail to fork -- which is
++ * very bad. Therefore we confirm PID #1 exists
++ * before issuing SPIGPWR
++ */
++ if (find_task_by_pid(1)) {
++ apm_queue_event(APM_LOW_BATTERY);
++ DEBUGPC("SIGPWR(init) ");
++ kill_proc(1, SIGPWR, 1);
++ } else
++ /*
++ * well, our situation is like this: we do not
++ * have any external power, we have a low
++ * battery and since PID #1 doesn't exist yet,
++ * we are early in the boot, likely before
++ * rootfs mount. We should just call it a day
++ */
++ apm_queue_event(APM_CRITICAL_SUSPEND);
++ }
++
+ /* Tell PMU we are taking care of this */
+ reg_set_bit_mask(pcf, PCF50633_REG_OOCSHDWN,
+ PCF50633_OOCSHDWN_TOTRST,
+--
+1.5.6.5
+