Patchwork rtc: s3c-rtc: fixup wake support for rtc

login
register
mail settings
Submitter Mark Brown
Date April 27, 2011, 5:37 p.m.
Message ID <1303925829-28483-1-git-send-email-broonie@opensource.wolfsonmicro.com>
Download mbox | patch
Permalink /patch/93096/
State New
Headers show

Comments

Mark Brown - April 27, 2011, 5:37 p.m.
From: Ben Dooks <ben-linux@fluff.org>

The driver is not balancing set_irq and disable_irq_wake() calls, so ensure
that it keeps track of whether the wake is enabled.

The fixes the following error on S3C6410 devices:

WARNING: at kernel/irq/manage.c:382 set_irq_wake+0x84/0xec()
Unbalanced IRQ 92 wake disable

Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 drivers/rtc/rtc-s3c.c |   13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)
Andrew Morton - April 29, 2011, 9:21 p.m.
On Wed, 27 Apr 2011 18:37:09 +0100
Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:

> The driver is not balancing set_irq and disable_irq_wake() calls, so ensure
> that it keeps track of whether the wake is enabled.
> 
> The fixes the following error on S3C6410 devices:
> 
> WARNING: at kernel/irq/manage.c:382 set_irq_wake+0x84/0xec()
> Unbalanced IRQ 92 wake disable

The patch applies to 2.6.38 and afaict the fix is needed in -stable, so
I have made it thus.  OK?
Mark Brown - April 30, 2011, 7:22 p.m.
On Fri, Apr 29, 2011 at 02:21:56PM -0700, Andrew Morton wrote:

> The patch applies to 2.6.38 and afaict the fix is needed in -stable, so
> I have made it thus.  OK?

Makes sense to me, yes.

Patch

diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index b3466c4..16512ec 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -46,6 +46,7 @@  static struct clk *rtc_clk;
 static void __iomem *s3c_rtc_base;
 static int s3c_rtc_alarmno = NO_IRQ;
 static int s3c_rtc_tickno  = NO_IRQ;
+static bool wake_en;
 static enum s3c_cpu_type s3c_rtc_cpu_type;
 
 static DEFINE_SPINLOCK(s3c_rtc_pie_lock);
@@ -562,8 +563,12 @@  static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state)
 	}
 	s3c_rtc_enable(pdev, 0);
 
-	if (device_may_wakeup(&pdev->dev))
-		enable_irq_wake(s3c_rtc_alarmno);
+	if (device_may_wakeup(&pdev->dev) && !wake_en) {
+		if (enable_irq_wake(s3c_rtc_alarmno) == 0)
+			wake_en = true;
+		else
+			dev_err(&pdev->dev, "enable_irq_wake failed\n");
+	}
 
 	return 0;
 }
@@ -579,8 +584,10 @@  static int s3c_rtc_resume(struct platform_device *pdev)
 		writew(tmp | ticnt_en_save, s3c_rtc_base + S3C2410_RTCCON);
 	}
 
-	if (device_may_wakeup(&pdev->dev))
+	if (device_may_wakeup(&pdev->dev) && wake_en) {
 		disable_irq_wake(s3c_rtc_alarmno);
+		wake_en = false;
+	}
 
 	return 0;
 }