X-Git-Url: http://www.pilppa.org/gitweb/gitweb.cgi?p=linux-2.6-omap-h63xx.git;a=blobdiff_plain;f=drivers%2Finput%2Fkeyboard%2Fomap-keypad.c;fp=drivers%2Finput%2Fkeyboard%2Fomap-keypad.c;h=98da278a1cc46ee1f5c8413d7b7b936ada3304bb;hp=058fa8b02c21ee1b939085c024c23884e2f6ca1d;hb=0d5f2216edfeb9904e0d6512f803b0f93871baaf;hpb=14fc69723d3442ef46f8f82b3f481e82f06a346d diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index 058fa8b02c2..98da278a1cc 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c @@ -33,13 +33,15 @@ #include #include #include +#include #include +#include #include #include -#include #include #include #include +#include #include #undef NEW_BOARD_LEARNING_MODE @@ -60,6 +62,8 @@ struct omap_kp { unsigned int cols; unsigned long delay; unsigned int debounce; + int suspended; + spinlock_t suspend_lock; }; static DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0); @@ -96,6 +100,14 @@ static u8 get_row_gpio_val(struct omap_kp *omap_kp) static irqreturn_t omap_kp_interrupt(int irq, void *dev_id) { 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()) { @@ -263,15 +275,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 @@ -284,7 +310,7 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) struct omap_kp *omap_kp; struct input_dev *input_dev; struct omap_kp_platform_data *pdata = pdev->dev.platform_data; - int i, col_idx, row_idx, irq_idx, ret; + int i, col_idx = 0, row_idx = 0, irq_idx, ret; if (!pdata->rows || !pdata->cols || !pdata->keymap) { printk(KERN_ERR "No rows, cols or keymap from pdata\n"); @@ -301,7 +327,9 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) platform_set_drvdata(pdev, omap_kp); + spin_lock_init(&omap_kp->suspend_lock); omap_kp->input = input_dev; + omap_kp->suspended = 0; /* Disable the interrupt for the MPUIO keyboard */ if (!cpu_is_omap24xx())