summaryrefslogtreecommitdiff
path: root/target/linux/s3c24xx/patches-2.6.26/1191-fix-gsm-resume-problems.patch.patch
blob: ed2cd98ef27b7afa03d066bd7a719987ffb6dd8c (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
From 5bba01c998f5c88ab2337df915e135e0d950c7a9 Mon Sep 17 00:00:00 2001
From: Andy Green <andy@openmoko.com>
Date: Fri, 25 Jul 2008 23:06:16 +0100
Subject: [PATCH] fix-gsm-resume-problems.patch

Signed-off-by: Andy Green <andy@openmoko.com>
---
 arch/arm/plat-s3c24xx/neo1973_pm_gsm.c |   19 +++++++++++++++++++
 drivers/serial/s3c2410.c               |   19 ++++++++++++++++++-
 2 files changed, 37 insertions(+), 1 deletions(-)

diff --git a/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c b/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c
index 149b866..6b6b2f4 100644
--- a/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c
+++ b/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c
@@ -18,6 +18,7 @@
 #include <linux/console.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
+#include <linux/resume-dependency.h>
 
 #include <asm/gpio.h>
 #include <asm/mach-types.h>
@@ -33,9 +34,12 @@
 struct gta01pm_priv {
 	int gpio_ngsm_en;
         int gpio_ndl_gsm;
+
 	struct console *con;
 };
 
+struct resume_dependency resume_dep_gsm_uart;
+
 static struct gta01pm_priv gta01_gsm;
 
 static struct console *find_s3c24xx_console(void)
@@ -179,6 +183,8 @@ static DEVICE_ATTR(reset, 0644, gsm_read, gsm_write);
 static DEVICE_ATTR(download, 0644, gsm_read, gsm_write);
 
 #ifdef CONFIG_PM
+
+static int gta01_gsm_resume(struct platform_device *pdev);
 static int gta01_gsm_suspend(struct platform_device *pdev, pm_message_t state)
 {
 	/* GPIO state is saved/restored by S3C2410 core GPIO driver, so we
@@ -189,11 +195,22 @@ static int gta01_gsm_suspend(struct platform_device *pdev, pm_message_t state)
 	if (machine_is_neo1973_gta02())
 		s3c2410_gpio_setpin(GTA02_GPIO_nDL_GSM, 1);
 
+	/* register our resume dependency on the appropriate UART being up */
+	resume_dep_gsm_uart.callback = gta01_gsm_resume;
+	resume_dep_gsm_uart.context = (void *)pdev;
+
+	s3c24xx_serial_register_resume_dependency(&resume_dep_gsm_uart, 0);
+
 	return 0;
 }
 
 static int gta01_gsm_resume(struct platform_device *pdev)
 {
+	if (resume_dep_gsm_uart.called_flag != 1)
+		return 0;
+
+	resume_dep_gsm_uart.called_flag++; /* only run once */
+
 	/* GPIO state is saved/restored by S3C2410 core GPIO driver, so we
 	 * don't need to do much here. */
 
@@ -279,6 +296,8 @@ static int __init gta01_gsm_probe(struct platform_device *pdev)
 	if (machine_is_neo1973_gta02())
 		s3c2410_gpio_setpin(GTA02_GPIO_nDL_GSM, 1);
 
+	init_resume_dependency_list(&resume_dep_gsm_uart);
+
 	return sysfs_create_group(&pdev->dev.kobj, &gta01_gsm_attr_group);
 }
 
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index bd87c79..32cceae 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -72,6 +72,7 @@
 #include <linux/serial.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
+#include <linux/resume-dependency.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -112,6 +113,8 @@ struct s3c24xx_uart_port {
 	struct clk			*clk;
 	struct clk			*baudclk;
 	struct uart_port		port;
+
+	struct resume_dependency	resume_dependency;
 };
 
 
@@ -1088,7 +1091,9 @@ static int s3c24xx_serial_probe(struct platform_device *dev,
 	ourport = &s3c24xx_serial_ports[probe_index];
 	probe_index++;
 
-	dbg("%s: initialising port %p...\n", __func__, ourport);
+	init_resume_dependency_list(&ourport->resume_dependency);
+
+	dbg("%s: initialising port %p...\n", __FUNCTION__, ourport);
 
 	ret = s3c24xx_serial_init_port(ourport, info, dev);
 	if (ret < 0)
@@ -1128,6 +1133,16 @@ static int s3c24xx_serial_suspend(struct platform_device *dev, pm_message_t stat
 	return 0;
 }
 
+void s3c24xx_serial_register_resume_dependency(struct resume_dependency *
+					      resume_dependency, int uart_index)
+{
+	struct s3c24xx_uart_port *ourport = &s3c24xx_serial_ports[uart_index];
+
+	register_resume_dependency(&ourport->resume_dependency,
+							     resume_dependency);
+}
+EXPORT_SYMBOL(s3c24xx_serial_register_resume_dependency);
+
 static int s3c24xx_serial_resume(struct platform_device *dev)
 {
 	struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
@@ -1141,6 +1156,8 @@ static int s3c24xx_serial_resume(struct platform_device *dev)
 		uart_resume_port(&s3c24xx_uart_drv, port);
 	}
 
+	callback_all_resume_dependencies(&ourport->resume_dependency);
+
 	return 0;
 }
 
-- 
1.5.6.3