summaryrefslogtreecommitdiffstats
path: root/target/linux/s3c24xx/patches-2.6.24/1284-fix-one-mmc-race.patch.patch
blob: 7acd823e3656db5dcbe640d3e442c23b935323cc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
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