summaryrefslogtreecommitdiffstats
path: root/target/linux/s3c24xx/patches-2.6.26/1130-From-cc08b5986dfd8d971ee46ce7045fb7863f99a92a-Mon-Se.patch
blob: c37e6fc0b539e736f79c91335a81835dccc5cf13 (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
From 348e7db53a04b7d98e0f63f372b86882a995d3c8 Mon Sep 17 00:00:00 2001
From: Matt Hsu <matt_hsu@openmoko.org>
Date: Fri, 25 Jul 2008 23:06:07 +0100
Subject: [PATCH] From cc08b5986dfd8d971ee46ce7045fb7863f99a92a Mon Sep 17 00:00:00 2001
 Subject: [PATCH] - add suspend/resume function of s3c24xx_hcd driver

Signed-off-by: Matt Hsu <matt_hsu@openmoko.org>
---
 drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c |   65 ++++++++++++++++++++++++++++++++
 drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h |   14 +++++++
 2 files changed, 79 insertions(+), 0 deletions(-)

diff --git a/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c b/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c
index af0066d..fdc69a0 100644
--- a/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c
+++ b/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c
@@ -1365,11 +1365,76 @@ static int s3c24xx_hcd_remove(struct platform_device * pdev) {
 	return 0;
 }
 
+#ifdef CONFIG_PM 
+
+static int s3c24xx_hcd_suspend(struct platform_device * pdev)
+{
+	struct s3c24xx_hcd_context * context = &hcd_context;	
+	unsigned long flags;
+
+	spin_lock_irqsave(&context->lock, flags);
+
+	context->suspend_regs.con 	= readl(context->base + S3C2410_SDICON);
+	context->suspend_regs.pre 	= readl(context->base + S3C2410_SDIPRE);
+	context->suspend_regs.cmdarg 	= readl(context->base + S3C2410_SDICMDARG);
+	context->suspend_regs.cmdcon 	= readl(context->base + S3C2410_SDICMDCON);
+	context->suspend_regs.cmdsta 	= readl(context->base + S3C2410_SDICMDSTAT);
+	context->suspend_regs.r0 	= readl(context->base + S3C2410_SDIRSP0);
+	context->suspend_regs.r1 	= readl(context->base + S3C2410_SDIRSP1);
+	context->suspend_regs.r2 	= readl(context->base + S3C2410_SDIRSP2);
+	context->suspend_regs.r3 	= readl(context->base + S3C2410_SDIRSP3);
+	context->suspend_regs.timer 	= readl(context->base + S3C2410_SDITIMER);
+	context->suspend_regs.bsize 	= readl(context->base + S3C2410_SDIBSIZE);
+	context->suspend_regs.datcon 	= readl(context->base + S3C2410_SDIDCON);
+	context->suspend_regs.datcnt 	= readl(context->base + S3C2410_SDIDCNT);
+	context->suspend_regs.datsta 	= readl(context->base + S3C2410_SDIDSTA);
+	context->suspend_regs.fsta 	= readl(context->base + S3C2410_SDIFSTA);
+	context->suspend_regs.imask   = readl(context->base + S3C2440_SDIIMSK);
+	
+	spin_unlock_irqrestore(&context->lock, flags);
+	return 0;
+}
+
+static int s3c24xx_hcd_resume(struct platform_device * pdev)
+{	
+	struct s3c24xx_hcd_context * context = &hcd_context;
+	unsigned long flags;
+
+	spin_lock_irqsave(&context->lock, flags);
+	
+	writel(context->suspend_regs.con, context->base + S3C2410_SDICON);
+	writel(context->suspend_regs.pre, context->base + S3C2410_SDIPRE);
+	writel(context->suspend_regs.cmdarg, context->base + S3C2410_SDICMDARG);
+	writel(context->suspend_regs.cmdcon, context->base + S3C2410_SDICMDCON);
+	writel(context->suspend_regs.cmdsta, context->base + S3C2410_SDICMDSTAT);
+	writel(context->suspend_regs.r0, context->base + S3C2410_SDIRSP0);
+	writel(context->suspend_regs.r1, context->base + S3C2410_SDIRSP1);
+	writel(context->suspend_regs.r2, context->base + S3C2410_SDIRSP2);
+	writel(context->suspend_regs.r3, context->base + S3C2410_SDIRSP3);
+	writel(context->suspend_regs.timer, context->base + S3C2410_SDITIMER);
+	writel(context->suspend_regs.bsize, context->base + S3C2410_SDIBSIZE);
+	writel(context->suspend_regs.datcon, context->base + S3C2410_SDIDCON);
+	writel(context->suspend_regs.datcnt, context->base + S3C2410_SDIDCNT);
+	writel(context->suspend_regs.datsta, context->base + S3C2410_SDIDSTA);
+	writel(context->suspend_regs.fsta, context->base + S3C2410_SDIFSTA);
+	writel(context->suspend_regs.imask, context->base + S3C2440_SDIIMSK);
+
+	spin_unlock_irqrestore(&context->lock, flags);
+	return 0;
+}
+
+#else
+#define s3c24xx_hcd_suspend = NULL
+#define s3c24xx_hcd_resume  = NULL
+#endif
+
 static struct platform_driver s3c24xx_hcd_sdio =
 {
 	.driver.name	= "s3c24xx-sdio",
 	.probe		= s3c24xx_hcd_probe,
 	.remove		= s3c24xx_hcd_remove,
+	.suspend    = s3c24xx_hcd_suspend,
+	.resume 	= s3c24xx_hcd_resume,
 };
 
 #ifdef CONFIG_DEBUG_FS
diff --git a/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h b/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h
index eb262fc..47fdd33 100644
--- a/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h
+++ b/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h
@@ -57,6 +57,20 @@ struct s3c24xx_hcd_context {
 
 	struct work_struct        io_work;
 	struct work_struct        irq_work;
+
+#ifdef CONFIG_PM
+	struct {
+		UINT32 		con;
+		UINT32 		pre;
+		UINT32 		cmdarg, cmdcon, cmdsta;
+		UINT32 		r0, r1, r2, r3;
+		UINT32 		timer;
+		UINT32 		bsize;
+		UINT32 		datcon, datcnt, datsta;
+		UINT32 		fsta;
+		UINT32 		imask;	
+	} suspend_regs;
+#endif
 };
 
 SDIO_STATUS s3c24xx_hcd_config(PSDHCD hcd, PSDCONFIG config);
-- 
1.5.6.3