aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Brownell <dbrownell@users.sourceforge.net>2009-06-29 02:50:08 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2009-06-29 03:00:14 -0400
commit666cbe342622c959ad95515918a1c1f8210c93f2 (patch)
tree3514f4e9cd2e462e754f3b4b0b5aa8d982c0cc5c
parenteef3e4cab72eaf5345e3c73b2975c194a714f6cd (diff)
Input: dm355evm_keys - use threaded IRQs
Convert the dm355evm keys driver to use IRQ threading instead of a private workqueue. IRQ threads were added to Linux after this driver was written, and in this case fit what the driver needs. (Although the non-shared thread costs more runtime memory.) Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r--drivers/input/misc/dm355evm_keys.c42
1 files changed, 20 insertions, 22 deletions
diff --git a/drivers/input/misc/dm355evm_keys.c b/drivers/input/misc/dm355evm_keys.c
index a63315ce4a6c..0918acae584a 100644
--- a/drivers/input/misc/dm355evm_keys.c
+++ b/drivers/input/misc/dm355evm_keys.c
@@ -23,30 +23,16 @@
23 * pressed, or its autorepeat kicks in, an event is sent. This driver 23 * pressed, or its autorepeat kicks in, an event is sent. This driver
24 * read those events from the small (32 event) queue and reports them. 24 * read those events from the small (32 event) queue and reports them.
25 * 25 *
26 * Because we communicate with the MSP430 using I2C, and all I2C calls
27 * in Linux sleep, we need to cons up a kind of threaded IRQ handler
28 * using a work_struct. The IRQ is active low, but we use it through
29 * the GPIO controller so we can trigger on falling edges.
30 *
31 * Note that physically there can only be one of these devices. 26 * Note that physically there can only be one of these devices.
32 * 27 *
33 * This driver was tested with firmware revision A4. 28 * This driver was tested with firmware revision A4.
34 */ 29 */
35struct dm355evm_keys { 30struct dm355evm_keys {
36 struct work_struct work;
37 struct input_dev *input; 31 struct input_dev *input;
38 struct device *dev; 32 struct device *dev;
39 int irq; 33 int irq;
40}; 34};
41 35
42static irqreturn_t dm355evm_keys_irq(int irq, void *_keys)
43{
44 struct dm355evm_keys *keys = _keys;
45
46 schedule_work(&keys->work);
47 return IRQ_HANDLED;
48}
49
50/* These initial keycodes can be remapped by dm355evm_setkeycode(). */ 36/* These initial keycodes can be remapped by dm355evm_setkeycode(). */
51static struct { 37static struct {
52 u16 event; 38 u16 event;
@@ -110,13 +96,12 @@ static struct {
110 { 0x3169, KEY_PAUSE, }, 96 { 0x3169, KEY_PAUSE, },
111}; 97};
112 98
113static void dm355evm_keys_work(struct work_struct *work) 99/* runs in an IRQ thread -- can (and will!) sleep */
100static irqreturn_t dm355evm_keys_irq(int irq, void *_keys)
114{ 101{
115 struct dm355evm_keys *keys; 102 struct dm355evm_keys *keys = _keys;
116 int status; 103 int status;
117 104
118 keys = container_of(work, struct dm355evm_keys, work);
119
120 /* For simplicity we ignore INPUT_COUNT and just read 105 /* For simplicity we ignore INPUT_COUNT and just read
121 * events until we get the "queue empty" indicator. 106 * events until we get the "queue empty" indicator.
122 * Reading INPUT_LOW decrements the count. 107 * Reading INPUT_LOW decrements the count.
@@ -183,6 +168,19 @@ static void dm355evm_keys_work(struct work_struct *work)
183 input_report_key(keys->input, keycode, 0); 168 input_report_key(keys->input, keycode, 0);
184 input_sync(keys->input); 169 input_sync(keys->input);
185 } 170 }
171 return IRQ_HANDLED;
172}
173
174/*
175 * Because we communicate with the MSP430 using I2C, and all I2C calls
176 * in Linux sleep, we use a threaded IRQ handler. The IRQ itself is
177 * active low, but we go through the GPIO controller so we can trigger
178 * on falling edges and not worry about enabling/disabling the IRQ in
179 * the keypress handling path.
180 */
181static irqreturn_t dm355evm_keys_hardirq(int irq, void *_keys)
182{
183 return IRQ_WAKE_THREAD;
186} 184}
187 185
188static int dm355evm_setkeycode(struct input_dev *dev, int index, int keycode) 186static int dm355evm_setkeycode(struct input_dev *dev, int index, int keycode)
@@ -233,7 +231,6 @@ static int __devinit dm355evm_keys_probe(struct platform_device *pdev)
233 231
234 keys->dev = &pdev->dev; 232 keys->dev = &pdev->dev;
235 keys->input = input; 233 keys->input = input;
236 INIT_WORK(&keys->work, dm355evm_keys_work);
237 234
238 /* set up "threaded IRQ handler" */ 235 /* set up "threaded IRQ handler" */
239 status = platform_get_irq(pdev, 0); 236 status = platform_get_irq(pdev, 0);
@@ -260,9 +257,10 @@ static int __devinit dm355evm_keys_probe(struct platform_device *pdev)
260 257
261 /* REVISIT: flush the event queue? */ 258 /* REVISIT: flush the event queue? */
262 259
263 status = request_irq(keys->irq, dm355evm_keys_irq, 260 status = request_threaded_irq(keys->irq,
264 IRQF_TRIGGER_FALLING, 261 dm355evm_keys_hardirq, dm355evm_keys_irq,
265 dev_name(&pdev->dev), keys); 262 IRQF_TRIGGER_FALLING,
263 dev_name(&pdev->dev), keys);
266 if (status < 0) 264 if (status < 0)
267 goto fail1; 265 goto fail1;
268 266