diff options
author | Anti Sullin <anti.sullin@artecdesign.ee> | 2007-09-26 00:01:17 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2007-09-26 00:01:17 -0400 |
commit | e15b02138b89d7bc053817e6f7601e92e29d371c (patch) | |
tree | ba0d3c404022e91bf072558ee4f0ef9de73ffe36 | |
parent | 006df3024431a50262d4a2898d25924f84fb697a (diff) |
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>
-rw-r--r-- | drivers/input/keyboard/gpio_keys.c | 52 | ||||
-rw-r--r-- | include/linux/gpio_keys.h | 1 |
2 files changed, 53 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) | |||
55 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | 55 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; |
56 | struct input_dev *input; | 56 | struct input_dev *input; |
57 | int i, error; | 57 | int i, error; |
58 | int wakeup = 0; | ||
58 | 59 | ||
59 | input = input_allocate_device(); | 60 | input = input_allocate_device(); |
60 | if (!input) | 61 | if (!input) |
@@ -100,6 +101,9 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
100 | goto fail; | 101 | goto fail; |
101 | } | 102 | } |
102 | 103 | ||
104 | if (button->wakeup) | ||
105 | wakeup = 1; | ||
106 | |||
103 | input_set_capability(input, type, button->code); | 107 | input_set_capability(input, type, button->code); |
104 | } | 108 | } |
105 | 109 | ||
@@ -111,6 +115,8 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
111 | goto fail; | 115 | goto fail; |
112 | } | 116 | } |
113 | 117 | ||
118 | device_init_wakeup(&pdev->dev, wakeup); | ||
119 | |||
114 | return 0; | 120 | return 0; |
115 | 121 | ||
116 | fail: | 122 | fail: |
@@ -129,6 +135,8 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) | |||
129 | struct input_dev *input = platform_get_drvdata(pdev); | 135 | struct input_dev *input = platform_get_drvdata(pdev); |
130 | int i; | 136 | int i; |
131 | 137 | ||
138 | device_init_wakeup(&pdev->dev, 0); | ||
139 | |||
132 | for (i = 0; i < pdata->nbuttons; i++) { | 140 | for (i = 0; i < pdata->nbuttons; i++) { |
133 | int irq = gpio_to_irq(pdata->buttons[i].gpio); | 141 | int irq = gpio_to_irq(pdata->buttons[i].gpio); |
134 | free_irq(irq, pdev); | 142 | free_irq(irq, pdev); |
@@ -139,9 +147,53 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) | |||
139 | return 0; | 147 | return 0; |
140 | } | 148 | } |
141 | 149 | ||
150 | |||
151 | #ifdef CONFIG_PM | ||
152 | static int gpio_keys_suspend(struct platform_device *pdev, pm_message_t state) | ||
153 | { | ||
154 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | ||
155 | int i; | ||
156 | |||
157 | if (device_may_wakeup(&pdev->dev)) { | ||
158 | for (i = 0; i < pdata->nbuttons; i++) { | ||
159 | struct gpio_keys_button *button = &pdata->buttons[i]; | ||
160 | if (button->wakeup) { | ||
161 | int irq = gpio_to_irq(button->gpio); | ||
162 | enable_irq_wake(irq); | ||
163 | } | ||
164 | } | ||
165 | } | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | static int gpio_keys_resume(struct platform_device *pdev) | ||
171 | { | ||
172 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | ||
173 | int i; | ||
174 | |||
175 | if (device_may_wakeup(&pdev->dev)) { | ||
176 | for (i = 0; i < pdata->nbuttons; i++) { | ||
177 | struct gpio_keys_button *button = &pdata->buttons[i]; | ||
178 | if (button->wakeup) { | ||
179 | int irq = gpio_to_irq(button->gpio); | ||
180 | disable_irq_wake(irq); | ||
181 | } | ||
182 | } | ||
183 | } | ||
184 | |||
185 | return 0; | ||
186 | } | ||
187 | #else | ||
188 | #define gpio_keys_suspend NULL | ||
189 | #define gpio_keys_resume NULL | ||
190 | #endif | ||
191 | |||
142 | struct platform_driver gpio_keys_device_driver = { | 192 | struct platform_driver gpio_keys_device_driver = { |
143 | .probe = gpio_keys_probe, | 193 | .probe = gpio_keys_probe, |
144 | .remove = __devexit_p(gpio_keys_remove), | 194 | .remove = __devexit_p(gpio_keys_remove), |
195 | .suspend = gpio_keys_suspend, | ||
196 | .resume = gpio_keys_resume, | ||
145 | .driver = { | 197 | .driver = { |
146 | .name = "gpio-keys", | 198 | .name = "gpio-keys", |
147 | } | 199 | } |
diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h index 265d17830a0f..c6d3a9de5634 100644 --- a/include/linux/gpio_keys.h +++ b/include/linux/gpio_keys.h | |||
@@ -8,6 +8,7 @@ struct gpio_keys_button { | |||
8 | int active_low; | 8 | int active_low; |
9 | char *desc; | 9 | char *desc; |
10 | int type; /* input event type (EV_KEY, EV_SW) */ | 10 | int type; /* input event type (EV_KEY, EV_SW) */ |
11 | int wakeup; /* configure the button as a wake-up source */ | ||
11 | }; | 12 | }; |
12 | 13 | ||
13 | struct gpio_keys_platform_data { | 14 | struct gpio_keys_platform_data { |