mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-12-23 22:59:55 +02:00
134 lines
6.1 KiB
Diff
134 lines
6.1 KiB
Diff
|
From d744c88c149269b95ec068c8615e492375415d6d Mon Sep 17 00:00:00 2001
|
||
|
From: Andy Green <andy@openmoko.com>
|
||
|
Date: Wed, 27 Aug 2008 04:09:30 +0900
|
||
|
Subject: [PATCH] fix-one-mmc-race.patch
|
||
|
|
||
|
Some boots from Qi trigger a symptom from this interesting race -->
|
||
|
|
||
|
[ 2.730000] Unable to handle kernel NULL pointer dereference at virtual address 00000248
|
||
|
[ 2.730000] pgd = c0004000
|
||
|
[ 2.735000] [00000248] *pgd=00000000
|
||
|
[ 2.735000] Internal error: Oops: 5 [#1] PREEMPT
|
||
|
[ 2.735000] Modules linked in:
|
||
|
[ 2.735000] CPU: 0 Not tainted (2.6.24-stable10_0c1587137aaf0ee3-mokodev #1071)
|
||
|
[ 2.735000] PC is at pcf50633_voltage_set+0x1c/0xfc
|
||
|
[ 2.735000] LR is at gta02_glamo_mmc_set_power+0xdc/0x128
|
||
|
[ 2.735000] pc : [<c01df570>] lr : [<c0034324>] psr: 60000013
|
||
|
[ 2.735000] sp : c7c57eb0 ip : c7c57ec8 fp : c7c57ec4
|
||
|
[ 2.735000] r10: c7cfca28 r9 : 00000000 r8 : c7c57f68
|
||
|
[ 2.735000] r7 : c7cfca68 r6 : c7cfcae0 r5 : 00000c80 r4 : 00000000
|
||
|
[ 2.735000] r3 : 00000000 r2 : 00000c80 r1 : 0000000a r0 : 00000c80
|
||
|
[ 2.735000] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel
|
||
|
[ 2.735000] Control: c000717f Table: 30004000 DAC: 00000017
|
||
|
[ 2.735000] Process kmmcd (pid: 102, stack limit = 0xc7c56268)
|
||
|
[ 2.735000] Stack: (0xc7c57eb0 to 0xc7c58000)
|
||
|
[ 2.735000] 7ea0: c0608c58 00000c80 c7c57edc c7c57ec8
|
||
|
[ 2.735000] 7ec0: c0034324 c01df564 c7cfca28 c7cfc800 c7c57f1c c7c57ee0 c0194de0 c0034258
|
||
|
[ 2.735000] 7ee0: c7c57f34 c7c57ef0 c01e6230 c005de5c 60000013 c7cfca28 c7cfc800 60000013
|
||
|
[ 2.735000] 7f00: c7cfca68 c7c57f68 00000000 c01e6778 c7c57f34 c7c57f20 c01e5d68 c0194da8
|
||
|
[ 2.735000] 7f20: c7cfc800 c7cfca08 c7c57f5c c7c57f38 c01e6810 c01e5cbc c0059278 c7c57f48
|
||
|
[ 2.735000] 7f40: c02d2ba0 00000002 c7c44420 c7c56000 c7c57f9c c7c57f60 c00592e0 c01e6788
|
||
|
[ 2.735000] 7f60: 00000002 c0059278 c0608d74 c04321cc c036e16c 00000000 c7c57fb0 c7c44420
|
||
|
[ 2.735000] 7f80: c7c56000 00000000 00000000 00000000 c7c57fd4 c7c57fa0 c005a068 c00591ec
|
||
|
[ 2.735000] 7fa0: c02d0624 00000000 c7c4c0e0 c005dc2c c7c57fb0 c7c57fb0 00000000 c7c56000
|
||
|
[ 2.735000] 7fc0: c7c44420 c0059f84 c7c57ff4 c7c57fd8 c005db28 c0059f94 00000000 00000000
|
||
|
[ 2.735000] 7fe0: 00000000 00000000 00000000 c7c57ff8 c004b170 c005dad8 ffffffff ffffffff
|
||
|
[ 2.735000] Backtrace:
|
||
|
[ 2.735000] [<c01df554>] (pcf50633_voltage_set+0x0/0xfc) from [<c0034324>] (gta02_glamo_mmc_set_power+0xdc/0x128)
|
||
|
[ 2.735000] r5:00000c80 r4:c0608c58
|
||
|
[ 2.735000] [<c0034248>] (gta02_glamo_mmc_set_power+0x0/0x128) from [<c0194de0>] (glamo_mci_set_ios+0x48/0x254)
|
||
|
[ 2.735000] r5:c7cfc800 r4:c7cfca28
|
||
|
[ 2.735000] [<c0194d98>] (glamo_mci_set_ios+0x0/0x254) from [<c01e5d68>] (mmc_power_up+0xbc/0x100)
|
||
|
[ 2.735000] [<c01e5cac>] (mmc_power_up+0x0/0x100) from [<c01e6810>] (mmc_rescan+0x98/0x1a8)
|
||
|
[ 2.735000] r5:c7cfca08 r4:c7cfc800
|
||
|
[ 2.735000] [<c01e6778>] (mmc_rescan+0x0/0x1a8) from [<c00592e0>] (run_workqueue+0x104/0x208)
|
||
|
[ 2.735000] r6:c7c56000 r5:c7c44420 r4:00000002
|
||
|
[ 2.735000] [<c00591dc>] (run_workqueue+0x0/0x208) from [<c005a068>] (worker_thread+0xe4/0xf8)
|
||
|
[ 2.735000] [<c0059f84>] (worker_thread+0x0/0xf8) from [<c005db28>] (kthread+0x60/0x94)
|
||
|
[ 2.735000] r6:c0059f84 r5:c7c44420 r4:c7c56000
|
||
|
[ 2.735000] [<c005dac8>] (kthread+0x0/0x94) from [<c004b170>] (do_exit+0x0/0x6f4)
|
||
|
[ 2.735000] r6:00000000 r5:00000000 r4:00000000
|
||
|
[ 2.735000] Code: e351000a e1a04000 e1a00002 8a000032 (e5943248)
|
||
|
[ 2.745000] ---[ end trace 123ec1d286354824 ]---
|
||
|
|
||
|
This problem was caused by insufficient timeout waiting for pcf50633 to resume
|
||
|
and broken code to detect timeout exhaustion.
|
||
|
|
||
|
Although I'd like to think it has something to do with mmc resume woes it should make a panic
|
||
|
and subsequent emergency spew on UART2 if that had been the case.
|
||
|
|
||
|
Took the opportunity to move the stuff to show completion of probe to later in the
|
||
|
pcf50633 probe and tighten readiness test.
|
||
|
|
||
|
Signed-off-by: Andy Green <andy@openmoko.com>
|
||
|
---
|
||
|
arch/arm/mach-s3c2440/mach-gta02.c | 4 ++--
|
||
|
drivers/i2c/chips/pcf50633.c | 12 ++++++++----
|
||
|
2 files changed, 10 insertions(+), 6 deletions(-)
|
||
|
|
||
|
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
|
||
|
index eadf88a..c15f072 100644
|
||
|
--- a/arch/arm/mach-s3c2440/mach-gta02.c
|
||
|
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
|
||
|
@@ -1357,7 +1357,7 @@ static void
|
||
|
gta02_glamo_mmc_set_power(unsigned char power_mode, unsigned short vdd)
|
||
|
{
|
||
|
int mv = 1650;
|
||
|
- int timeout = 100;
|
||
|
+ int timeout = 500;
|
||
|
|
||
|
printk(KERN_DEBUG "mmc_set_power(power_mode=%u, vdd=%u\n",
|
||
|
power_mode, vdd);
|
||
|
@@ -1377,7 +1377,7 @@ gta02_glamo_mmc_set_power(unsigned char power_mode, unsigned short vdd)
|
||
|
while (pcf50633_ready(pcf50633_global) && (timeout--))
|
||
|
msleep(5);
|
||
|
|
||
|
- if (!timeout) {
|
||
|
+ if (timeout < 0) {
|
||
|
printk(KERN_ERR"gta02_glamo_mmc_set_power "
|
||
|
"BAILING on timeout\n");
|
||
|
return;
|
||
|
diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
|
||
|
index b90ea8c..bac307e 100644
|
||
|
--- a/drivers/i2c/chips/pcf50633.c
|
||
|
+++ b/drivers/i2c/chips/pcf50633.c
|
||
|
@@ -2151,8 +2151,6 @@ static int pcf50633_detect(struct i2c_adapter *adapter, int address, int kind)
|
||
|
goto exit_free;
|
||
|
}
|
||
|
|
||
|
- pcf50633_global = pcf;
|
||
|
-
|
||
|
init_resume_dependency_list(&pcf->resume_dependency);
|
||
|
|
||
|
populate_sysfs_group(pcf);
|
||
|
@@ -2228,11 +2226,13 @@ static int pcf50633_detect(struct i2c_adapter *adapter, int address, int kind)
|
||
|
backlight_update_status(pcf->backlight);
|
||
|
}
|
||
|
|
||
|
- pcf->probe_completed = 1;
|
||
|
-
|
||
|
if (pcf->pdata->flag_use_apm_emulation)
|
||
|
apm_get_power_status = pcf50633_get_power_status;
|
||
|
|
||
|
+ pcf->probe_completed = 1;
|
||
|
+ pcf50633_global = pcf;
|
||
|
+ dev_info(&new_client->dev, "probe completed\n");
|
||
|
+
|
||
|
/* if platform was interested, give him a chance to register
|
||
|
* platform devices that switch power with us as the parent
|
||
|
* at registration time -- ensures suspend / resume ordering
|
||
|
@@ -2476,6 +2476,10 @@ int pcf50633_ready(struct pcf50633_data *pcf)
|
||
|
if (!pcf)
|
||
|
return -EACCES;
|
||
|
|
||
|
+ /* this was seen during boot with Qi, mmc_rescan racing us */
|
||
|
+ if (!pcf->probe_completed)
|
||
|
+ return -EACCES;
|
||
|
+
|
||
|
if ((pcf->suspend_state != PCF50633_SS_RUNNING) &&
|
||
|
(pcf->suspend_state < PCF50633_SS_COMPLETED_RESUME))
|
||
|
return -EBUSY;
|
||
|
--
|
||
|
1.5.6.5
|
||
|
|