summary refs log tree commit diff
path: root/drivers/input/keyboard
diff options
context:
space:
mode:
authorAnti Sullin <anti.sullin@artecdesign.ee>2007-09-26 00:01:17 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2007-09-26 00:01:17 -0400
commite15b02138b89d7bc053817e6f7601e92e29d371c (patch)
treeba0d3c404022e91bf072558ee4f0ef9de73ffe36 /drivers/input/keyboard
parent006df3024431a50262d4a2898d25924f84fb697a (diff)
downloadlinux-e15b02138b89d7bc053817e6f7601e92e29d371c.tar.gz
Input: gpio-keys - add suspend/resume support
This patch adds suspend/resume support and enables wakeup from
gpio_keys buttons.

Signed-off-by: Anti Sullin <anti.sullin@artecdesign.ee>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r--drivers/input/keyboard/gpio_keys.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index b3069bc00f03..3d6820b4465b 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -55,6 +55,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
 	struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
 	struct input_dev *input;
 	int i, error;
+	int wakeup = 0;
 
 	input = input_allocate_device();
 	if (!input)
@@ -100,6 +101,9 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
 			goto fail;
 		}
 
+		if (button->wakeup)
+			wakeup = 1;
+
 		input_set_capability(input, type, button->code);
 	}
 
@@ -111,6 +115,8 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
 		goto fail;
 	}
 
+	device_init_wakeup(&pdev->dev, wakeup);
+
 	return 0;
 
  fail:
@@ -129,6 +135,8 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
 	struct input_dev *input = platform_get_drvdata(pdev);
 	int i;
 
+	device_init_wakeup(&pdev->dev, 0);
+
 	for (i = 0; i < pdata->nbuttons; i++) {
 		int irq = gpio_to_irq(pdata->buttons[i].gpio);
 		free_irq(irq, pdev);
@@ -139,9 +147,53 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
 	return 0;
 }
 
+
+#ifdef CONFIG_PM
+static int gpio_keys_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+	int i;
+
+	if (device_may_wakeup(&pdev->dev)) {
+		for (i = 0; i < pdata->nbuttons; i++) {
+			struct gpio_keys_button *button = &pdata->buttons[i];
+			if (button->wakeup) {
+				int irq = gpio_to_irq(button->gpio);
+				enable_irq_wake(irq);
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int gpio_keys_resume(struct platform_device *pdev)
+{
+	struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+	int i;
+
+	if (device_may_wakeup(&pdev->dev)) {
+		for (i = 0; i < pdata->nbuttons; i++) {
+			struct gpio_keys_button *button = &pdata->buttons[i];
+			if (button->wakeup) {
+				int irq = gpio_to_irq(button->gpio);
+				disable_irq_wake(irq);
+			}
+		}
+	}
+
+	return 0;
+}
+#else
+#define gpio_keys_suspend	NULL
+#define gpio_keys_resume	NULL
+#endif
+
 struct platform_driver gpio_keys_device_driver = {
 	.probe		= gpio_keys_probe,
 	.remove		= __devexit_p(gpio_keys_remove),
+	.suspend	= gpio_keys_suspend,
+	.resume		= gpio_keys_resume,
 	.driver		= {
 		.name	= "gpio-keys",
 	}