summaryrefslogtreecommitdiff
path: root/target/linux/s3c24xx/patches-2.6.26/1084-fix-glamo-mci-fake-reset-opcode-in-suspend.patch.patch
blob: f1ac5a4b42954f7f9fa6bbe1ab90a15116f2d880 (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
134
135
136
137
138
139
140
141
From f26eee35ae154c2be8a6e23f3e6a45f01f50f7a7 Mon Sep 17 00:00:00 2001
From: warmcat <andy@warmcat.com>
Date: Fri, 25 Jul 2008 23:06:01 +0100
Subject: [PATCH] fix-glamo-mci-fake-reset-opcode-in-suspend.patch

---
 arch/arm/mach-s3c2440/mach-gta02.c |    4 ++--
 drivers/mfd/glamo/glamo-core.c     |   16 +++++++++-------
 drivers/mfd/glamo/glamo-mci.c      |   29 +++++++++++++++++++++--------
 3 files changed, 32 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
index 750fd97..f18c8fd 100644
--- a/arch/arm/mach-s3c2440/mach-gta02.c
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
@@ -1281,6 +1281,8 @@ static void __init gta02_machine_init(void)
 		s3c2410_gpio_setpin(GTA02_GPIO_nWLAN_RESET, 1);
 		break;
 	}
+	mangle_glamo_res_by_system_rev();
+	platform_device_register(&gta02_glamo_dev);
 
 	platform_device_register(&s3c_device_spi_acc);
 	platform_device_register(&gta01_button_dev);
@@ -1291,8 +1293,6 @@ static void __init gta02_machine_init(void)
 	platform_device_register(&gta01_led_dev);
 	platform_device_register(&gta02_led_dev);
 
-	mangle_glamo_res_by_system_rev();
-	platform_device_register(&gta02_glamo_dev);
 
 	platform_device_register(&gta02_sdio_dev);
 
diff --git a/drivers/mfd/glamo/glamo-core.c b/drivers/mfd/glamo/glamo-core.c
index 2076e61..4d8e47f 100644
--- a/drivers/mfd/glamo/glamo-core.c
+++ b/drivers/mfd/glamo/glamo-core.c
@@ -822,6 +822,8 @@ static void glamo_power(struct glamo_core *glamo,
 {
 	spin_lock(&glamo->lock);
 
+	dev_dbg(&glamo->pdev->dev, "***** glamo_power -> %d\n", new_state);
+
 	switch (new_state) {
 	case GLAMO_POWER_ON:
 		/* power up PLL1 and PLL2 */
@@ -1026,13 +1028,6 @@ static int __init glamo_probe(struct platform_device *pdev)
 	glamo_mci_def_pdata.glamo_irq_is_wired =
 					glamo->pdata->glamo_irq_is_wired;
 
-	glamo_mmc_dev.dev.parent = &pdev->dev;
-	/* we need it later to give to the engine enable and disable */
-	glamo_mci_def_pdata.pglamo = glamo;
-	mangle_mem_resources(glamo_mmc_dev.resource,
-			     glamo_mmc_dev.num_resources, glamo->mem);
-	platform_device_register(&glamo_mmc_dev);
-
 	glamo_2d_dev.dev.parent = &pdev->dev;
 	mangle_mem_resources(glamo_2d_dev.resource,
 			     glamo_2d_dev.num_resources, glamo->mem);
@@ -1065,6 +1060,13 @@ static int __init glamo_probe(struct platform_device *pdev)
 	glamo_spigpio_dev.dev.platform_data = glamo->pdata->spigpio_info;
 	platform_device_register(&glamo_spigpio_dev);
 
+	glamo_mmc_dev.dev.parent = &pdev->dev;
+	/* we need it later to give to the engine enable and disable */
+	glamo_mci_def_pdata.pglamo = glamo;
+	mangle_mem_resources(glamo_mmc_dev.resource,
+			     glamo_mmc_dev.num_resources, glamo->mem);
+	platform_device_register(&glamo_mmc_dev);
+
 	/* only request the generic, hostbus and memory controller MMIO */
 	glamo->mem = request_mem_region(glamo->mem->start,
 					GLAMO_REGOFS_VIDCAP, "glamo-core");
diff --git a/drivers/mfd/glamo/glamo-mci.c b/drivers/mfd/glamo/glamo-mci.c
index bbbbe4d..d8847c5 100644
--- a/drivers/mfd/glamo/glamo-mci.c
+++ b/drivers/mfd/glamo/glamo-mci.c
@@ -405,11 +405,11 @@ static void glamo_mci_send_request(struct mmc_host *mmc)
 	u16 * reg_resp = (u16 *)(host->base + GLAMO_REG_MMC_CMD_RSP1);
 	u16 status;
 	int n;
+	int timeout = 100000000;
 
 	if (host->suspending) {
-		cmd->error = -EIO;
-		if (cmd->data)
-			cmd->data->error = -EIO;
+		dev_err(&host->pdev->dev, "faking cmd %d "
+			"during suspend\n", cmd->opcode);
 		mmc_request_done(mmc, mrq);
 		return;
 	}
@@ -502,10 +502,23 @@ static void glamo_mci_send_request(struct mmc_host *mmc)
 	 * our own INT# line"
 	 */
 	if (!glamo_mci_def_pdata.pglamo->irq_works) {
-		/* we have faith we will get an "interrupt"... */
-		while (!(readw_dly(glamo_mci_def_pdata.pglamo->base +
-			 GLAMO_REG_IRQ_STATUS) & GLAMO_IRQ_MMC))
+		/*
+		 * we have faith we will get an "interrupt"...
+		 * but something insane like suspend problems can mean
+		 * we spin here forever, so we timeout after a LONG time
+		 */
+		while ((!(readw_dly(glamo_mci_def_pdata.pglamo->base +
+			 GLAMO_REG_IRQ_STATUS) & GLAMO_IRQ_MMC)) &&
+		       (timeout--))
 			;
+
+		if (timeout < 0) {
+			if (cmd->data->error)
+				cmd->data->error = -ETIMEDOUT;
+			dev_err(&host->pdev->dev, "Payload timeout\n");
+			return;
+		}
+
 		/* yay we are an interrupt controller! -- call the ISR */
 		glamo_mci_irq(IRQ_GLAMO(GLAMO_IRQIDX_MMC),
 			      irq_desc + IRQ_GLAMO(GLAMO_IRQIDX_MMC));
@@ -529,6 +542,7 @@ static void glamo_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 
 static void glamo_mci_reset(struct glamo_mci_host *host)
 {
+	dev_dbg(&host->pdev->dev, "******* glamo_mci_reset\n");
 	/* reset MMC controller */
 	writew_dly(GLAMO_CLOCK_MMC_RESET | GLAMO_CLOCK_MMC_DG_TCLK |
 		   GLAMO_CLOCK_MMC_EN_TCLK | GLAMO_CLOCK_MMC_DG_M9CLK |
@@ -803,8 +817,7 @@ static int glamo_mci_suspend(struct platform_device *dev, pm_message_t state)
 	struct glamo_mci_host 	*host = mmc_priv(mmc);
 
 	host->suspending++;
-
-	return  mmc_suspend_host(mmc, state);
+	return mmc_suspend_host(mmc, state);
 }
 
 static int glamo_mci_resume(struct platform_device *dev)
-- 
1.5.6.3