public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Unmask omap-keypad interrupt on suspend
@ 2006-08-11 10:43 andrzej zaborowski
  2006-08-11 10:52 ` Tony Lindgren
  0 siblings, 1 reply; 5+ messages in thread
From: andrzej zaborowski @ 2006-08-11 10:43 UTC (permalink / raw)
  To: Linux-OMAP

[-- Attachment #1: Type: text/plain, Size: 375 bytes --]

Prevent keyboard interrupt from staying masked when omap-keypad driver
is suspended. Otherwise, when the driver is compiled in, the kernel
won't resume from a sleep state if any key on the keypad was still
pressed during suspending. This is because the driver masks keyboard
interrupt when irq is received and doesn't unmask it until after keys
are released.
-- 
balrog 2oo6

[-- Attachment #2: linux-keypad-suspend2.patch --]
[-- Type: application/octet-stream, Size: 2112 bytes --]

--- a/drivers/input/keyboard/omap-keypad.c	2006-08-05 05:18:01.000000000 +0000
+++ b/drivers/input/keyboard/omap-keypad.c	2006-08-10 06:19:11.000000000 +0000
@@ -33,6 +33,7 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
+#include <linux/spinlock.h>
 #include <asm/arch/irqs.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/hardware.h>
@@ -59,6 +60,8 @@ struct omap_kp {
 	int irq;
 	unsigned int rows;
 	unsigned int cols;
+	int suspended;
+	spinlock_t suspend_lock;
 };
 
 DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0);
@@ -99,6 +102,13 @@ static irqreturn_t omap_kp_interrupt(int
 				     struct pt_regs *regs)
 {
 	struct omap_kp *omap_kp = dev_id;
+	unsigned long flags;
+	spin_lock_irqsave(&omap_kp->suspend_lock, flags);
+
+	if (omap_kp->suspended)
+		return IRQ_HANDLED;
+
+	spin_unlock_irqrestore(&omap_kp->suspend_lock, flags);
 
 	/* disable keyboard interrupt and schedule for handling */
 	if (cpu_is_omap24xx()) {
@@ -271,15 +281,29 @@ static DEVICE_ATTR(enable, S_IRUGO | S_I
 #ifdef CONFIG_PM
 static int omap_kp_suspend(struct platform_device *dev, pm_message_t state)
 {
-	/* Nothing yet */
+	struct omap_kp *omap_kp = platform_get_drvdata(dev);
+	unsigned long flags;
+	spin_lock_irqsave(&omap_kp->suspend_lock, flags);
+
+	/*
+	 * Re-enable the interrupt in case it has been masked by the
+	 * handler and a key is still pressed.  We need the interrupt
+	 * to wake us up from suspended.
+	 */
+	if (cpu_class_is_omap1())
+		omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
 
+	omap_kp->suspended = 1;
+
+	spin_unlock_irqrestore(&omap_kp->suspend_lock, flags);
 	return 0;
 }
 
 static int omap_kp_resume(struct platform_device *dev)
 {
-	/* Nothing yet */
+	struct omap_kp *omap_kp = platform_get_drvdata(dev);
 
+	omap_kp->suspended = 0;
 	return 0;
 }
 #else
@@ -351,6 +375,9 @@ static int __init omap_kp_probe(struct p
 		}
 	}
 
+	spin_lock_init(&omap_kp->suspend_lock);
+	omap_kp->suspended = 0;
+
 	init_timer(&omap_kp->timer);
 	omap_kp->timer.function = omap_kp_timer;
 	omap_kp->timer.data = (unsigned long) omap_kp;

[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Unmask omap-keypad interrupt on suspend
  2006-08-11 10:43 [PATCH] Unmask omap-keypad interrupt on suspend andrzej zaborowski
@ 2006-08-11 10:52 ` Tony Lindgren
  0 siblings, 0 replies; 5+ messages in thread
From: Tony Lindgren @ 2006-08-11 10:52 UTC (permalink / raw)
  To: balrogg; +Cc: Linux-OMAP

* andrzej zaborowski <balrog@zabor.org> [060811 13:46]:
> Prevent keyboard interrupt from staying masked when omap-keypad driver
> is suspended. Otherwise, when the driver is compiled in, the kernel
> won't resume from a sleep state if any key on the keypad was still
> pressed during suspending. This is because the driver masks keyboard
> interrupt when irq is received and doesn't unmask it until after keys
> are released.

No Signed-off-by: ? :)

Tony

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] Unmask omap-keypad interrupt on suspend
@ 2006-08-11 11:28 andrzej zaborowski
  2006-08-11 11:31 ` andrzej zaborowski
  0 siblings, 1 reply; 5+ messages in thread
From: andrzej zaborowski @ 2006-08-11 11:28 UTC (permalink / raw)
  To: Linux-OMAP, Tony Lindgren

Prevent keyboard interrupt from staying masked when omap-keypad driver
is suspended. Otherwise, when the driver is compiled in, the kernel
won't resume from a sleep state if any key on the keypad was still
pressed during suspending. This is because the driver masks keyboard
interrupt when irq is received and doesn't unmask it until after keys
are released.

Signed-off-by: Andrzej Zaborowski <balrog@zabor.org>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Unmask omap-keypad interrupt on suspend
  2006-08-11 11:28 andrzej zaborowski
@ 2006-08-11 11:31 ` andrzej zaborowski
  0 siblings, 0 replies; 5+ messages in thread
From: andrzej zaborowski @ 2006-08-11 11:31 UTC (permalink / raw)
  To: Linux-OMAP, Tony Lindgren

[-- Attachment #1: Type: text/plain, Size: 474 bytes --]

[Another try. Sorry for spam, I keep forgetting something.]

Prevent keyboard interrupt from staying masked when omap-keypad driver
is suspended. Otherwise, when the driver is compiled in, the kernel
won't resume from a sleep state if any key on the keypad was still
pressed during suspending. This is because the driver masks keyboard
interrupt when irq is received and doesn't unmask it until after keys
are released.

Signed-off-by: Andrzej Zaborowski <balrog@zabor.org>

[-- Attachment #2: linux-keypad-suspend2.patch --]
[-- Type: application/octet-stream, Size: 2112 bytes --]

--- a/drivers/input/keyboard/omap-keypad.c	2006-08-05 05:18:01.000000000 +0000
+++ b/drivers/input/keyboard/omap-keypad.c	2006-08-10 06:19:11.000000000 +0000
@@ -33,6 +33,7 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
+#include <linux/spinlock.h>
 #include <asm/arch/irqs.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/hardware.h>
@@ -59,6 +60,8 @@ struct omap_kp {
 	int irq;
 	unsigned int rows;
 	unsigned int cols;
+	int suspended;
+	spinlock_t suspend_lock;
 };
 
 DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0);
@@ -99,6 +102,13 @@ static irqreturn_t omap_kp_interrupt(int
 				     struct pt_regs *regs)
 {
 	struct omap_kp *omap_kp = dev_id;
+	unsigned long flags;
+	spin_lock_irqsave(&omap_kp->suspend_lock, flags);
+
+	if (omap_kp->suspended)
+		return IRQ_HANDLED;
+
+	spin_unlock_irqrestore(&omap_kp->suspend_lock, flags);
 
 	/* disable keyboard interrupt and schedule for handling */
 	if (cpu_is_omap24xx()) {
@@ -271,15 +281,29 @@ static DEVICE_ATTR(enable, S_IRUGO | S_I
 #ifdef CONFIG_PM
 static int omap_kp_suspend(struct platform_device *dev, pm_message_t state)
 {
-	/* Nothing yet */
+	struct omap_kp *omap_kp = platform_get_drvdata(dev);
+	unsigned long flags;
+	spin_lock_irqsave(&omap_kp->suspend_lock, flags);
+
+	/*
+	 * Re-enable the interrupt in case it has been masked by the
+	 * handler and a key is still pressed.  We need the interrupt
+	 * to wake us up from suspended.
+	 */
+	if (cpu_class_is_omap1())
+		omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
 
+	omap_kp->suspended = 1;
+
+	spin_unlock_irqrestore(&omap_kp->suspend_lock, flags);
 	return 0;
 }
 
 static int omap_kp_resume(struct platform_device *dev)
 {
-	/* Nothing yet */
+	struct omap_kp *omap_kp = platform_get_drvdata(dev);
 
+	omap_kp->suspended = 0;
 	return 0;
 }
 #else
@@ -351,6 +375,9 @@ static int __init omap_kp_probe(struct p
 		}
 	}
 
+	spin_lock_init(&omap_kp->suspend_lock);
+	omap_kp->suspended = 0;
+
 	init_timer(&omap_kp->timer);
 	omap_kp->timer.function = omap_kp_timer;
 	omap_kp->timer.data = (unsigned long) omap_kp;

[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] Unmask omap-keypad interrupt on suspend
@ 2006-08-17 20:09 andrzej zaborowski
  0 siblings, 0 replies; 5+ messages in thread
From: andrzej zaborowski @ 2006-08-17 20:09 UTC (permalink / raw)
  To: Linux-OMAP

[-- Attachment #1: Type: text/plain, Size: 237 bytes --]

Prevent keyboard interrupt from staying masked when omap-keypad driver
is suspended to allow this interrupt to trigger a system wake up.
Locks are used as suggested by Juha Yrjölä.

Signed-off-by: Andrzej Zaborowski <balrog@zabor.org>

[-- Attachment #2: linux-keypad-suspend3.patch --]
[-- Type: application/octet-stream, Size: 2174 bytes --]

--- a/drivers/input/keyboard/omap-keypad.c	2006-07-06 02:48:09.000000000 +0000
+++ b/drivers/input/keyboard/omap-keypad.c	2006-08-17 21:51:41.000000000 +0000
@@ -33,6 +33,7 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
+#include <linux/spinlock.h>
 #include <asm/arch/irqs.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/hardware.h>
@@ -59,6 +60,8 @@ struct omap_kp {
 	int irq;
 	unsigned int rows;
 	unsigned int cols;
+	int suspended;
+	spinlock_t suspend_lock;
 };
 
 DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0);
@@ -99,6 +102,14 @@ static irqreturn_t omap_kp_interrupt(int
 				     struct pt_regs *regs)
 {
 	struct omap_kp *omap_kp = dev_id;
+	unsigned long flags;
+
+	spin_lock_irqsave(&omap_kp->suspend_lock, flags);
+	if (omap_kp->suspended) {
+		spin_unlock_irqrestore(&omap_kp->suspend_lock, flags);
+		return IRQ_HANDLED;
+	}
+	spin_unlock_irqrestore(&omap_kp->suspend_lock, flags);
 
 	/* disable keyboard interrupt and schedule for handling */
 	if (cpu_is_omap24xx()) {
@@ -269,15 +280,29 @@ static DEVICE_ATTR(enable, S_IRUGO | S_I
 #ifdef CONFIG_PM
 static int omap_kp_suspend(struct platform_device *dev, pm_message_t state)
 {
-	/* Nothing yet */
+	struct omap_kp *omap_kp = platform_get_drvdata(dev);
+	unsigned long flags;
+	spin_lock_irqsave(&omap_kp->suspend_lock, flags);
+
+	/*
+	 * Re-enable the interrupt in case it has been masked by the
+	 * handler and a key is still pressed.  We need the interrupt
+	 * to wake us up from suspended.
+	 */
+	if (cpu_class_is_omap1())
+		omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
 
+	omap_kp->suspended = 1;
+
+	spin_unlock_irqrestore(&omap_kp->suspend_lock, flags);
 	return 0;
 }
 
 static int omap_kp_resume(struct platform_device *dev)
 {
-	/* Nothing yet */
+	struct omap_kp *omap_kp = platform_get_drvdata(dev);
 
+	omap_kp->suspended = 0;
 	return 0;
 }
 #else
@@ -349,6 +374,9 @@ static int __init omap_kp_probe(struct p
 		}
 	}
 
+	spin_lock_init(&omap_kp->suspend_lock);
+	omap_kp->suspended = 0;
+
 	init_timer(&omap_kp->timer);
 	omap_kp->timer.function = omap_kp_timer;
 	omap_kp->timer.data = (unsigned long) omap_kp;

[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2006-08-17 20:09 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-08-11 10:43 [PATCH] Unmask omap-keypad interrupt on suspend andrzej zaborowski
2006-08-11 10:52 ` Tony Lindgren
  -- strict thread matches above, loose matches on Subject: below --
2006-08-11 11:28 andrzej zaborowski
2006-08-11 11:31 ` andrzej zaborowski
2006-08-17 20:09 andrzej zaborowski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox