aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Hsu <matt_hsu@openmoko.org>2008-11-19 17:09:41 +0000
committerAndy Green <agreen@pads.home.warmcat.com>2008-11-19 17:09:41 +0000
commit13a6a30e83edf90374d5ce4e336315a96ebf394d (patch)
treead9cdbedc012e058d62b50583f38f2d37eb77a23
parent8b6c3b85838ec2cc1e4ad9231f7fe59be7b8ccfe (diff)
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>
-rw-r--r--drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c65
-rw-r--r--drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h14
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 af0066d9a96..fdc69a0f6a3 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 eb262fc4b25..47fdd331d6a 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);