From 3ee675dc2330d99f3d8a111dc587ee1ef6dddac3 Mon Sep 17 00:00:00 2001 From: andrzej zaborowski Date: Tue, 5 Sep 2006 17:52:25 +0300 Subject: [PATCH] [PATCH] Unmask omap-keypad interrupt on suspend MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Tony Lindgren --- drivers/input/keyboard/omap-keypad.c | 32 ++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index 98bbe976c8d..9608f7e91e1 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -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 irq, void *dev_id, 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_IWUSR, omap_kp_enable_show, omap_kp_enabl #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 platform_device *pdev) } } + 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; -- 2.41.1