WiFi is down after resuming. This is result from the config of SDIO
controller is broken after resuming. So I add the cb function of
suspend/resume for s3c24xx_hcd device to keep the config. Now the WiFi
can work even after suspend/resume cycle. 

Matt
>From 2d727270e57c25044d112c6ad9807ddc07d5199a Mon Sep 17 00:00:00 2001
From: matt_hsu <[EMAIL PROTECTED]>
Date: Wed, 30 Apr 2008 17:30:53 +0800
Subject: [PATCH] - add suspend/resume function of s3c24xx_hcd 


Signed-off-by: Matt Hsu <[EMAIL PROTECTED]>
---
 drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c |   56 ++++++++++++++++++++++++++++++++
 drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h |   15 ++++++++
 2 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c b/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c
index 8c3bbbc..69f3bdd 100644
--- a/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c
+++ b/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.c
@@ -1250,6 +1250,62 @@ static void s3c24xx_hcd_hw_cleanup(struct s3c24xx_hcd_context * context)
 			      context->io_buffer, context->io_buffer_dma);
 }
 
+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;
+}
+
 static int s3c24xx_hcd_pnp_probe(struct pnp_dev *pBusDevice, const struct pnp_device_id *pId)
 {
 	SDIO_STATUS status = SDIO_STATUS_SUCCESS;
diff --git a/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h b/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h
index eb262fc..c2361b4 100644
--- a/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h
+++ b/drivers/sdio/hcd/s3c24xx/s3c24xx_hcd.h
@@ -57,6 +57,21 @@ 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);
-- 
debian.1.5.3.7.1-dirty

Reply via email to